<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Shap Bytes - Shap Bytes</title>
    <subtitle>Share space of code and musings for Shap</subtitle>
    <link rel="self" type="application/atom+xml" href="https://shapath.com.np/posts/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2034-02-08T00:00:00+00:00</updated>
    <id>https://shapath.com.np/posts/atom.xml</id>
    <entry xml:lang="en">
        <title>Mikrotik DDNS IPv6 via Cloudflare</title>
        <published>2034-02-08T00:00:00+00:00</published>
        <updated>2034-02-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-cloudflare-ddns-for-mikrotik/"/>
        <id>https://shapath.com.np/posts/til-cloudflare-ddns-for-mikrotik/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-cloudflare-ddns-for-mikrotik/">&lt;p&gt;The majority of Mikrotik scripts I came across online utilized an external service to locate my IP address, and then used a Global API key to modify the DNS records on Cloudflare. I was searching for a more secure method to update the Cloudflare DNS record.&lt;&#x2F;p&gt;
&lt;p&gt;Creating an authorization token within the Cloudflare Dashboard with limited credentials allows this script to ensure that your entire Cloudflare account is not compromised even if your key leaks.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# ** CONFIGURE SECTION **
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# IPv6 interface
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; wanif    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;ether1&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Cloudflare section
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Using Access Token Instead of Global API Key
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; key      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;access_token&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; zoneId   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;zone_id&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# To Find HostId&#x2F;Record Id, Need to Call Cloudflare API; See Below
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; hostId   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;record_id&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Domain hostname
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; hostName &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;shapath.com.np&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# ** END OF CONFIGURE SECTION **
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Get WAN interface IPv6 address
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:global&lt;&#x2F;span&gt;&lt;span&gt; ip6wan
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:local&lt;&#x2F;span&gt;&lt;span&gt; ip6new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;ipv6 address get [&#x2F;ipv6 address find interface=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;wanif global&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; address]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:set&lt;&#x2F;span&gt;&lt;span&gt; ip6new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:pick &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:tostr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; 0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:find &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:tostr &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span&gt;:len &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; = 0) do&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;  :log error &amp;quot;[Cloudflare DDNS] Could not get IPv6 for interface &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;wanif&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;  :error &amp;quot;[Cloudflare DDNS] Could not get IPv6 for interface &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;wanif&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;:if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new != &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6wan) do&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    :local url    &amp;quot;https:&#x2F;&#x2F;api.cloudflare.com&#x2F;client&#x2F;v4&#x2F;zones&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;zoneId&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;dns_records&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;hostId&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    :local header &amp;quot;Authorization: Bearer &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;, content-type: application&#x2F;json&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    :local data   &amp;quot;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;AAAA&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;hostName&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;ttl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:60,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;proxied&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;:false}&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# :log info &amp;quot;[Cloudflare DDNS] URL: $url&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# :log info &amp;quot;[Cloudflare DDNS] HEADER: $header&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# :log info &amp;quot;[Cloudflare DDNS] DATA: $data&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    :log info &amp;quot;[Cloudflare DDNS] Updating host &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;hostName&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; address to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    :do {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;      &#x2F;tool fetch mode=https http-method=put http-header-field=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; http-data=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt; url=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;url
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;      :log info &amp;quot;[Cloudflare DDNS] Updated: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;ip6new&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;      
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    } on-error={ 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;      :log error &amp;quot;[Cloudflare DDNS] Failed to update&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    };
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;where-is-my-record-id-host-id&quot;&gt;Where is my Record Id&#x2F;Host Id?&lt;a class=&quot;zola-anchor&quot; href=&quot;#where-is-my-record-id-host-id&quot; aria-label=&quot;Anchor link for: where-is-my-record-id-host-id&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span&gt; --request GET &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --url https:&#x2F;&#x2F;api.cloudflare.com&#x2F;client&#x2F;v4&#x2F;zones&#x2F;{zone_id}&#x2F;dns_records &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --header &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --header &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;X-Auth-Email: {cloudflare_email@email.com}&amp;#39; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --header &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;X-Auth-Key: {global_api_token}&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since this Global API Key is only used once to find the correct record id, it is fine for me.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;source&quot;&gt;Source&lt;a class=&quot;zola-anchor&quot; href=&quot;#source&quot; aria-label=&quot;Anchor link for: source&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dudanov&#x2F;mikrotik-cloudflare-ddns-scripts&#x2F;blob&#x2F;master&#x2F;cloudflare6ddns&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;dudanov&#x2F;mikrotik-cloudflare-ddns-scripts&#x2F;blob&#x2F;master&#x2F;cloudflare6ddns&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Self-Hosted Tailscale DERP Server</title>
        <published>2025-09-14T00:00:00+00:00</published>
        <updated>2025-09-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-tailscale-self-hosted-derp/"/>
        <id>https://shapath.com.np/posts/til-tailscale-self-hosted-derp/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-tailscale-self-hosted-derp/">&lt;p&gt;Setting up a custom DERP (Designated Encrypted Relay for Packets) server for Tailscale allows you to route traffic through your own infrastructure when direct peer-to-peer connections aren’t possible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-self-host&quot;&gt;Why Self-Host?&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-self-host&quot; aria-label=&quot;Anchor link for: why-self-host&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Tailscale’s default DERP servers can be quite slow and their QoS (Quality of Service) severely impacts performance for long-term streaming use cases. While they work perfectly fine for one-time use cases like quick file transfers or occasional remote access, sustained traffic like video streaming or large file synchronization suffers from bandwidth limitations and throttling.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Self-hosting your own DERP server eliminates these performance bottlenecks and gives you full control over the relay infrastructure. It’s not a dramatic speedboot you’re going to see, but it’s quite a bit faster for sustained workloads.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;running-the-derp-server&quot;&gt;Running the DERP Server&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-the-derp-server&quot; aria-label=&quot;Anchor link for: running-the-derp-server&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Deploy the DERP server using Docker with client verification enabled:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span&gt; docker run -d &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  --name derper &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  --restart unless-stopped &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -e DERP_DOMAIN=derper.domain.com.np &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -e DERP_VERIFY_CLIENTS=true &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -v &#x2F;var&#x2F;run&#x2F;tailscale&#x2F;tailscaled.sock:&#x2F;var&#x2F;run&#x2F;tailscale&#x2F;tailscaled.sock &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -p 8480:80 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -p 8443:443 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  -p 3478:3478&#x2F;udp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;  fredliang&#x2F;derper
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;DERP_VERIFY_CLIENTS=true&lt;&#x2F;code&gt; flag ensures only your Tailscale clients can connect, authenticating through the mounted Unix socket.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-custom-derp-region&quot;&gt;Configuring Custom DERP Region&lt;a class=&quot;zola-anchor&quot; href=&quot;#configuring-custom-derp-region&quot; aria-label=&quot;Anchor link for: configuring-custom-derp-region&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Add your custom DERP server to Tailscale’s ACL configuration in the Tailscale dashboard using a region ID between 900-999:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;derpMap&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;span&gt;		&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;OmitDefaultRegions&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;		&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Regions&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;			&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;901&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;				&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RegionID&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;901&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;				&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RegionCode&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;selfhosted-derp&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;				&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;regionName&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;AsiaPacific&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;				&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Nodes&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&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;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Name&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;:     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;						&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RegionID&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;901&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;						&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;HostName&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;derper.domain.com&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;						&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;STUNPort&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;3478&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;						&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;DERPPort&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;443&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;					}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;				]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;			}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;		}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;	}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;reverse-proxy-for-ssl-certificates&quot;&gt;Reverse Proxy for SSL Certificates&lt;a class=&quot;zola-anchor&quot; href=&quot;#reverse-proxy-for-ssl-certificates&quot; aria-label=&quot;Anchor link for: reverse-proxy-for-ssl-certificates&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Use Caddy to handle SSL certificate issuance and reverse proxy to the DERP server:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;caddyfile&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-caddyfile &quot;&gt;&lt;code class=&quot;language-caddyfile&quot; data-lang=&quot;caddyfile&quot;&gt;&lt;span&gt;http:&#x2F;&#x2F;derper.domain.com {
&lt;&#x2F;span&gt;&lt;span&gt;    reverse_proxy localhost:8480
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This configuration allows Let’s Encrypt to issue certificates from within the Docker container through the reverse proxy setup.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;key-benefits&quot;&gt;Key Benefits&lt;a class=&quot;zola-anchor&quot; href=&quot;#key-benefits&quot; aria-label=&quot;Anchor link for: key-benefits&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Custom routing&lt;&#x2F;strong&gt;: Control where your Tailscale traffic is relayed&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Reduced latency&lt;&#x2F;strong&gt;: Place DERP servers closer to your devices&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced privacy&lt;&#x2F;strong&gt;: Keep relay traffic on your own infrastructure&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Client verification&lt;&#x2F;strong&gt;: Only authenticated Tailscale clients can use the relay&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Server-Side Events (SSE) with Phoenix&#x2F;Elixir</title>
        <published>2024-08-29T00:00:00+00:00</published>
        <updated>2024-08-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/server-side-events-with-phoenix/"/>
        <id>https://shapath.com.np/posts/server-side-events-with-phoenix/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/server-side-events-with-phoenix/">&lt;h2 id=&quot;understanding-server-sent-events&quot;&gt;Understanding Server-Sent Events&lt;a class=&quot;zola-anchor&quot; href=&quot;#understanding-server-sent-events&quot; aria-label=&quot;Anchor link for: understanding-server-sent-events&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Server-Sent Events (SSE) is a powerful technology that allows servers to push data to web clients over HTTP connections. It provides a way for servers to send real-time updates to clients without the need for long-polling or WebSockets. This makes SSE an excellent choice for scenarios where you need one-way communication from the server to the client, such as live updates, notifications, or streaming data.&lt;&#x2F;p&gt;
&lt;p&gt;While Phoenix has traditionally leaned towards WebSockets for real-time, bidirectional communication, SSE offers a simpler, unidirectional approach that’s particularly well-suited for certain use cases. In this post, we’ll explore how to implement SSE using &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;hexdocs.pm&#x2F;plug&#x2F;readme.html&quot;&gt;Plug&lt;&#x2F;a&gt; in Phoenix, with the help of &lt;code&gt;send_chunked&#x2F;2&lt;&#x2F;code&gt;, &lt;code&gt;chunk&#x2F;2&lt;&#x2F;code&gt;, and &lt;code&gt;EventSource&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-the-controller&quot;&gt;Setting Up the Controller&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-the-controller&quot; aria-label=&quot;Anchor link for: setting-up-the-controller&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;First, we need to set up a controller action that will handle our SSE connection:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sse&lt;&#x2F;span&gt;&lt;span&gt;(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _params) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;  conn
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; put_resp_header(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;cache-control&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;no-cache&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; put_resp_content_type(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;text&#x2F;event-stream&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; send_chunked(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;200&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s examine this code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We set the response content type to &lt;code&gt;&quot;text&#x2F;event-stream&quot;&lt;&#x2F;code&gt;, which is crucial for SSE.&lt;&#x2F;li&gt;
&lt;li&gt;We use &lt;code&gt;send_chunked(200)&lt;&#x2F;code&gt; to initiate a chunked response with a 200 status code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;using-send-chunked&quot;&gt;Using &lt;code&gt;send_chunked&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#using-send-chunked&quot; aria-label=&quot;Anchor link for: using-send-chunked&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;send_chunked&#x2F;2&lt;&#x2F;code&gt; function is key to implementing SSE in Plug. It does two important things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;It sends the HTTP headers to the client, indicating that the response will be sent in chunks.&lt;&#x2F;li&gt;
&lt;li&gt;It switches the connection to chunked mode, allowing us to send data in multiple chunks over time.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;sending-events-with-chunk&quot;&gt;Sending Events with &lt;code&gt;chunk&lt;&#x2F;code&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sending-events-with-chunk&quot; aria-label=&quot;Anchor link for: sending-events-with-chunk&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Once we’ve initiated a chunked response, we can use the &lt;code&gt;chunk&#x2F;2&lt;&#x2F;code&gt; function to send data to the client:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;send_events&lt;&#x2F;span&gt;&lt;span&gt;(conn) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reduce_while(mock_llm_response()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;case&lt;&#x2F;span&gt;&lt;span&gt; chunk(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; chunk) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;      {:ok&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Process&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        {:cont&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn}
&lt;&#x2F;span&gt;&lt;span&gt;      {:error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:closed} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        {:halt&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn}
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;We iterate over a list of mock responses.&lt;&#x2F;li&gt;
&lt;li&gt;For each chunk, we use &lt;code&gt;chunk(conn, chunk)&lt;&#x2F;code&gt; to send the data.&lt;&#x2F;li&gt;
&lt;li&gt;We handle the result of &lt;code&gt;chunk&#x2F;2&lt;&#x2F;code&gt;:
&lt;ul&gt;
&lt;li&gt;If it’s successful (&lt;code&gt;{:ok, conn}&lt;&#x2F;code&gt;), we continue the loop.&lt;&#x2F;li&gt;
&lt;li&gt;If there’s an error (e.g., the connection is closed), we halt the loop.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;In the last step conn is returned&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;formatting-the-event-data&quot;&gt;Formatting the Event Data&lt;a class=&quot;zola-anchor&quot; href=&quot;#formatting-the-event-data&quot; aria-label=&quot;Anchor link for: formatting-the-event-data&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;For SSE to work correctly, each event should be formatted as follows:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;data: Your event data here\n\n
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note the double newline at the end - this is crucial for separating events. In our example, we format the data like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;data: #{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\n\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;API&#x2F;Server-sent_events&#x2F;Using_server-sent_events#examples&quot;&gt;Read more about the format here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;client-side-using-eventsource&quot;&gt;Client-Side: Using EventSource&lt;a class=&quot;zola-anchor&quot; href=&quot;#client-side-using-eventsource&quot; aria-label=&quot;Anchor link for: client-side-using-eventsource&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;On the client side, you can use the EventSource API to receive these server-sent events:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#d8dee9;&quot;&gt;eventSource &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;EventSource&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;sse&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;eventSource&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;onmessage &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;(event) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;console&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;log&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Received data:&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;event&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The EventSource API automatically handles reconnection and parsing of the event stream, making it easy to work with SSE on the client side.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mime-support&quot;&gt;MIME Support&lt;a class=&quot;zola-anchor&quot; href=&quot;#mime-support&quot; aria-label=&quot;Anchor link for: mime-support&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;When implementing SSE in Phoenix, you might encounter a Phoenix.NotAcceptableError related to MIME types. This error occurs when Phoenix doesn’t recognize the text&#x2F;event-stream MIME type. This is because Phoenix only accepts certain headers that are controlled by plug :accepts, [].&lt;&#x2F;p&gt;
&lt;p&gt;The fix is straightforward. Add the following to your configuration:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# In config&#x2F;config.exs
&lt;&#x2F;span&gt;&lt;span&gt;config :mime&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:types&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; %{
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;text&#x2F;event-stream&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sse&amp;quot;&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 style=&quot;color:#616e88;&quot;&gt;# In your router.ex
&lt;&#x2F;span&gt;&lt;span&gt;plug :accepts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;html&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sse&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;full-source-code&quot;&gt;Full Source Code&lt;a class=&quot;zola-anchor&quot; href=&quot;#full-source-code&quot; aria-label=&quot;Anchor link for: full-source-code&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Copy the snippet and save into file.&lt;&#x2F;li&gt;
&lt;li&gt;Run with &lt;code&gt;elixir file_name.exs&lt;&#x2F;code&gt; or &lt;code&gt;iex file_name.exs&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Copy of code available at &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;theshapguy&#x2F;c0567433a862bb0d8dc727ca30606016&quot;&gt;Github Gist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;env elixir
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Mix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;install(
&lt;&#x2F;span&gt;&lt;span&gt;  [
&lt;&#x2F;span&gt;&lt;span&gt;    {:phoenix_playground&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;~&amp;gt; 0.1.5&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    {:jason&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;~&amp;gt; 1.3&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;  config: [
&lt;&#x2F;span&gt;&lt;span&gt;    mime: [
&lt;&#x2F;span&gt;&lt;span&gt;      types: %{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;text&#x2F;event-stream&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sse&amp;quot;&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;span style=&quot;color:#616e88;&quot;&gt;  # force: true
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defmodule &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSEController &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Phoenix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Controller&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;formats: [:html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:sse]
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Phoenix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Component
&lt;&#x2F;span&gt;&lt;span&gt;  plug(:put_layout&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  plug(:put_view&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;__MODULE__&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 style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span&gt;(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _params) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    render(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:index)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;index&lt;&#x2F;span&gt;&lt;span&gt;(assigns) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~H&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;div style=&amp;quot;padding:16px;max-width:400px;margin:auto&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;p style=&amp;quot;font-family:sans-serif&amp;quot;&amp;gt;&amp;lt;b&amp;gt;Hello Sever-Side Events (SSE)&amp;lt;&#x2F;b&amp;gt;&amp;lt;&#x2F;p&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;br&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;div id=&amp;quot;response&amp;quot; style=&amp;quot;font-family:sans-serif;&amp;quot;&amp;gt;&amp;lt;&#x2F;div&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;&#x2F;div&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        const eventSource = new EventSource(&amp;#39;&#x2F;sse&amp;#39;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        const responseDiv = document.getElementById(&amp;#39;response&amp;#39;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        eventSource.onmessage = function(event) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;          console.log(event.data);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;          responseDiv.innerHTML = responseDiv.innerHTML + event.data;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        };
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        eventSource.addEventListener(&amp;#39;done&amp;#39;, function(event) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            console.log(&amp;#39;Stream complete&amp;#39;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            eventSource.close();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        });
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        eventSource.onerror = function(error) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            console.error(&amp;#39;EventSource failed:&amp;#39;, error);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;            eventSource.close();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;        };
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;&#x2F;script&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;sse&lt;&#x2F;span&gt;&lt;span&gt;(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _params) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    conn
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; put_resp_content_type(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;text&#x2F;event-stream&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; put_resp_header(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;cache-control&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;no-cache&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; send_chunked(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;200&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; send_events()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;send_events&lt;&#x2F;span&gt;&lt;span&gt;(conn) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reduce_while(mock_llm_response()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span&gt; chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Plug&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chunk(conn&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; chunk) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;        {:ok&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;          # Mimicing for ChatGPT style response
&lt;&#x2F;span&gt;&lt;span&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Process&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;          {:cont&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        {:error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:closed} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;-&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;          {:halt&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; conn}
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defp &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;mock_llm_response &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;~s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;[{&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.143675Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;Here&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.198081Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; is&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.252113Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; a&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.306116Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; two&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.360078Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;-line&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.415174Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; summary&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.468991Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; about&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.523294Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; the&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.577272Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; planets&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.631504Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span&gt;n&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.686003Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Our&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.74176Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; solar&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.797425Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; system&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.85169Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; consists&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.907339Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; of&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:21.961274Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; eight&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.016623Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; planets&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.0705Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;,&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.124703Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; each&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.178571Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; with&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.232894Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; its&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.286941Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; own&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.341096Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; unique&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.395072Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; size&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.4492Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;,&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.503167Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; composition&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.557346Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;,&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.611345Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; and&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.6654Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; features&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.720629Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;,&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.774724Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; ranging&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.831603Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; from&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.886015Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; tiny&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.941614Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Mercury&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:22.99643Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; to&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.050478Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; massive&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.104922Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; gas&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.159261Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; giant&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.214676Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Jupiter&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.270369Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;.&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.32482Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; The&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.379032Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; planets&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.433923Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; are&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.488128Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; categorized&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.543358Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; into&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.597931Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; two&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.653839Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; main&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.709756Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; groups&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.764332Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;:&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.818894Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; rocky&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.874536Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; inner&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.93003Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; planets&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:23.98419Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; like&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.0399Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Earth&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.095414Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; and&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.14959Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Mars&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.205239Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;,&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.259446Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; and&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.313489Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; g&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.367633Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;ase&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.42172Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;ous&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.476205Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; outer&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.53165Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; planets&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.585701Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; like&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.639802Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Saturn&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.695259Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; and&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.749622Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot; Uran&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.805156Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;us&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.859499Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;.&amp;quot;,&amp;quot;done&amp;quot;:false},
&lt;&#x2F;span&gt;&lt;span&gt;    {&amp;quot;model&amp;quot;:&amp;quot;llama3.1&amp;quot;,&amp;quot;created_at&amp;quot;:&amp;quot;2024-08-29T05:10:24.913578Z&amp;quot;,&amp;quot;response&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;done&amp;quot;:true,&amp;quot;done_reason&amp;quot;:&amp;quot;stop&amp;quot;}]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Jason&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;decode!()
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;    # Making it working well for EventSource; \n \n line structure
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Map&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;response&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;data: #{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;\n\n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defmodule &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSERouter &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Phoenix&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Router
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;  # import Phoenix.LiveView.Router
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  pipeline :browser &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    plug(:accepts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;html&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sse&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;    plug(:fetch_session)
&lt;&#x2F;span&gt;&lt;span&gt;    plug(:put_root_layout&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;html: {&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;PhoenixPlayground&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Layout&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:root})
&lt;&#x2F;span&gt;&lt;span&gt;    plug(:put_secure_browser_headers)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  scope &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    pipe_through(:browser)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    get(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSEController&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:index)
&lt;&#x2F;span&gt;&lt;span&gt;    get(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;sse&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSEController&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:sse)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;    # Just to get rid of errors
&lt;&#x2F;span&gt;&lt;span&gt;    get(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;favicon.ico&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSEController&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:index)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;PhoenixPlayground&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;start(plug: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SSERouter&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Retrieval-Augmented Generation (RAG) with Elixir</title>
        <published>2024-07-30T00:00:00+00:00</published>
        <updated>2024-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/beginning-rag-elixir/"/>
        <id>https://shapath.com.np/posts/beginning-rag-elixir/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/beginning-rag-elixir/">&lt;blockquote&gt;
&lt;p&gt;This is my initial attempt at implementing RAG in Elixir. My goal is to develop a system similar to PrivateGPT by gaining a deeper understanding of the concepts and improving chunking and metadata techniques. For this project, I intentionally avoided using LangChain or OpenAI to explore the foundational aspects of RAG.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Checkout the code implementation &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;theshapguy&#x2F;rag-elixir&#x2F;blob&#x2F;1fa5682797186d3581995771c1be83ef76950b57&#x2F;lib&#x2F;agents&#x2F;hello.ex&quot; target=&quot;_blank&quot;&gt;here&lt;&#x2F;a&gt;. The code is at a very alpha and just shows a simple RAG. I plan to develop this code further and want to build something similar to &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zylon-ai&#x2F;private-gpt&quot;&gt;PrivateGPT&lt;&#x2F;a&gt; in Elixir.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Retrieval-Augmented Generation (RAG) is a technique that enables Large Language Models (LLMs) to incorporate relevant and up-to-date information, allowing the LLM to address contexts it hasn’t been specifically trained on. RAG extends the powerful capabilities of LLMs into specific domains without the need for retraining, making it a cost-effective approach to enhancing LLM outputs, ensuring they remain relevant, accurate, and useful across various contexts.&lt;&#x2F;p&gt;
&lt;span style=&quot;font-size:0.5em;text-align:right&quot;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;towardsdatascience.com&#x2F;rag-vs-finetuning-which-is-the-best-tool-to-boost-your-llm-application-94654b1eaba7&quot;&gt;Image Source&lt;&#x2F;a&gt;
&lt;&#x2F;span&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;rag-elixir-image.webp&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;RAG is a multi step process;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Document Ingestion&lt;&#x2F;li&gt;
&lt;li&gt;Chunking&lt;&#x2F;li&gt;
&lt;li&gt;Embedding&lt;&#x2F;li&gt;
&lt;li&gt;Vector Database&lt;&#x2F;li&gt;
&lt;li&gt;Retrival &amp;amp; Query Processing&lt;&#x2F;li&gt;
&lt;li&gt;Generation &amp;amp; Output&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;document-ingestion-input&quot;&gt;Document Ingestion (Input)&lt;a class=&quot;zola-anchor&quot; href=&quot;#document-ingestion-input&quot; aria-label=&quot;Anchor link for: document-ingestion-input&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Document ingestion involves using a HTML document, a PDF, an image, or an audio file as input for an LLM model. For this project, I used the &lt;code&gt;Reddit S1&lt;&#x2F;code&gt; filing as a knowledge base, providing prompts and questions based on it. For this initial attempt, I didn’t focus on tables and pictures within the S1 filing, as I aimed to develop a basic system capable of replying using the knowledge base.&lt;&#x2F;p&gt;
&lt;p&gt;To read a PDF file, libraries such as pdftotext can be used. Here’s a simple command to read the file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Not using stream for now
&lt;&#x2F;span&gt;&lt;span&gt;{:ok&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; contents} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;File&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;read(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&#x2F;priv&#x2F;static&#x2F;s1-file.md&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# OR 
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;{:ok&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; response} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;HTTPoison&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;get(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;gist.githubusercontent.com&#x2F;theshapguy&#x2F;d8633451460dac8a6cf6f0cf75a00f74&#x2F;raw&#x2F;a796d8af1452caa5d6857e67d40041a2ccaa3b14&#x2F;RedditS1_RAG.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;_contents &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;body
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;chunking&quot;&gt;Chunking&lt;a class=&quot;zola-anchor&quot; href=&quot;#chunking&quot; aria-label=&quot;Anchor link for: chunking&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Chunking converts a large corpus into manageable, byte-sized content, improving retrieval efficiency and relevance by enabling the system to fetch specific, pertinent sections rather than entire documents.&lt;&#x2F;p&gt;
&lt;p&gt;By breaking larger texts into smaller chunks, we can selectively feed the most relevant pieces into the LLM, maximizing the use of available context and enabling the model to work with larger amounts of information than its default context window would allow. Ideally, each chunk should contain text about a specific topic, concept, or idea.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;chunk_document&lt;&#x2F;span&gt;&lt;span&gt;(content &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\\&lt;&#x2F;span&gt;&lt;span&gt; html_input()) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;TextChunker&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split(content)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Enum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;map(&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;text)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;findings&quot;&gt;Findings&lt;a class=&quot;zola-anchor&quot; href=&quot;#findings&quot; aria-label=&quot;Anchor link for: findings&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Without chunking, the LLM model struggles to find the right information; larger context windows increase hallucinations.&lt;&#x2F;li&gt;
&lt;li&gt;Smaller chunks capture more granular semantic information, while larger chunks retain more context.&lt;&#x2F;li&gt;
&lt;li&gt;Summaries can be used instead of the whole document, speeding up retrieval and enhancing meaningful content retrieval.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@anuragmishra_27746&#x2F;five-levels-of-chunking-strategies-in-rag-notes-from-gregs-video-7b735895694d&quot;&gt;Chuking styles&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;embedding-vector-database&quot;&gt;Embedding &amp;amp; Vector Database&lt;a class=&quot;zola-anchor&quot; href=&quot;#embedding-vector-database&quot; aria-label=&quot;Anchor link for: embedding-vector-database&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Imagine you have a big box of different toys. Each toy is special and unique in its own way. Now, let’s say you want to organize these toys so you can easily find similar ones.
Embeddings are like giving each toy a special set of numbers that describe it. These numbers tell us things about the toy without us having to look at it directly.
For example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A toy car might get numbers like: [4, 2, 1]
(4 for “has wheels”, 2 for “made of metal”, 1 for “small size”)&lt;&#x2F;li&gt;
&lt;li&gt;A stuffed animal might get: [0, 0, 3]
(0 for “no wheels”, 0 for “not metal”, 3 for “soft and cuddly”)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, when you want to find toys that are similar, you can just look at their numbers. Toys with similar numbers are probably alike in real life too!&lt;&#x2F;p&gt;
&lt;p&gt;Embeddings turn words, sentences, or documents into a vector list of a certain dimension, allowing prompts (queries) to be compared quickly. These embeddings are stored in a vector database such as ChromaDB or PGVector for retrieval when a query is made.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;findings-1&quot;&gt;Findings&lt;a class=&quot;zola-anchor&quot; href=&quot;#findings-1&quot; aria-label=&quot;Anchor link for: findings-1&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;I found that most people are using ChromaDB, however I preferred to use PGVector as it allowed me to iterate faster and I didn’t have to learn about another technology.&lt;&#x2F;li&gt;
&lt;li&gt;Multiple models can be used for embedding; I used BAAI&#x2F;bge-small-en-v1.5 for local testing. Local models can be as powerful as OpenAI’s embeddings.&lt;&#x2F;li&gt;
&lt;li&gt;Make sure to embed the document and retrive with the same model and vector size.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;defmodule &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Agents&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Repo&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Migrations&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;CreateSections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Ecto&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Migration
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;change &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    execute &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;CREATE EXTENSION IF NOT EXISTS vector&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    create table(:sections) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;      add :embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:vector&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;size: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;384
&lt;&#x2F;span&gt;&lt;span&gt;      add :chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:text
&lt;&#x2F;span&gt;&lt;span&gt;      add :metadata&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:map
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      timestamps(type: :utc_datetime)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    create index(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sections&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;embedding vector_cosine_ops&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;using: :hnsw)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;schema &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;sections&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    field :chunk&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:string
&lt;&#x2F;span&gt;&lt;span&gt;    field :metadata&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:map
&lt;&#x2F;span&gt;&lt;span&gt;    field :embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Pgvector&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Ecto&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Vector
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    timestamps(type: :utc_datetime)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;embed_chunks&lt;&#x2F;span&gt;&lt;span&gt;(chunk) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    %{embedding: embedding} &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=
&lt;&#x2F;span&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Nx&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Serving&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;batched_run(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;SentenceTransformer&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; chunk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;trim())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Sections&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;create_section(
&lt;&#x2F;span&gt;&lt;span&gt;      %{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;chunk&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; chunk &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;trim()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;embedding&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; embedding}
&lt;&#x2F;span&gt;&lt;span&gt;      )
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;retrival-query-processing&quot;&gt;Retrival &amp;amp; Query Processing&lt;a class=&quot;zola-anchor&quot; href=&quot;#retrival-query-processing&quot; aria-label=&quot;Anchor link for: retrival-query-processing&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;When querying, such as “What are the risk factors for Reddit?”, the first step is converting the text into a vector embedding. We use the same embedding model and vector size for both the query and document chunks for accurate similarity comparisons.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vector-search-process&quot;&gt;Vector Search Process&lt;a class=&quot;zola-anchor&quot; href=&quot;#vector-search-process&quot; aria-label=&quot;Anchor link for: vector-search-process&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Once we have the query embedding, we perform a vector search to find similar chunks of data. This search is based on the principle that semantically similar texts will have similar vector representations.
We typically use cosine similarity to measure how close two vectors are. Cosine similarity values range from -1 to 1, with 1 indicating perfect similarity. For our Reddit risk factors query, we might find chunks discussing various business risks, user engagement challenges, or regulatory concerns.
Vector search is incredibly efficient compared to traditional text search, allowing us to quickly sift through millions of chunks to find the most relevant ones.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In PostgresSQL using Ecto&#x2F;Elixir there is already a query function for this.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;reranking-with-cross-encoders&quot;&gt;Reranking with Cross-Encoders&lt;a class=&quot;zola-anchor&quot; href=&quot;#reranking-with-cross-encoders&quot; aria-label=&quot;Anchor link for: reranking-with-cross-encoders&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;After the initial vector search, we employ a reranking step using a cross-encoder. In our case, we use the &lt;code&gt;cross-encoder&#x2F;ms-marco-MiniLM-L-6-v2&lt;&#x2F;code&gt; model. Unlike the initial embedding model, which encodes the query and documents separately, the cross-encoder considers the query and each potential chunk together.
The cross-encoder generates a single, unified representation of the paired texts by considering the interactions between them at each layer of the transformer. This allows for a more nuanced understanding of relevance, often leading to improved ranking.
While cross-encoders provide better accuracy, they are computationally more expensive. That’s why we use them for reranking a smaller set of initially retrieved chunks rather than for the initial search.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# In postgressql we can do a vector search using max_inner_product rather than cosine similarity
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# under the hood (same thing)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;search_document_embedding&lt;&#x2F;span&gt;&lt;span&gt;(embedding) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    from(s &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;in __MODULE__&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      select: {s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;chunk}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      
&lt;&#x2F;span&gt;&lt;span&gt;      order_by: max_inner_product(s&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;embedding&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;^&lt;&#x2F;span&gt;&lt;span&gt;embedding)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      limit: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;20
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Repo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;all()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;generation-output&quot;&gt;Generation &amp;amp; Output&lt;a class=&quot;zola-anchor&quot; href=&quot;#generation-output&quot; aria-label=&quot;Anchor link for: generation-output&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Once we have all the relevant context from the vector database, we can create a prompt within a  prompt window. We collect all the relevent context and create a prompt as such below.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;    prompt &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    [INST] &amp;lt;&amp;lt;SYS&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    If you do not know the answer, just say that you don&amp;#39;t know. Use two sentences maximum and keep the answer concise.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;lt;&amp;lt;&#x2F;SYS&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    Question: #{&lt;&#x2F;span&gt;&lt;span&gt;question}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    Context: #{&lt;&#x2F;span&gt;&lt;span&gt;context}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;[&#x2F;INST]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    client &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Ollama&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;init()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Ollama&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;completion(client&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      model: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;llama3.1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;      prompt: prompt
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&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;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In conclusion, Retrieval-Augmented Generation (RAG) with Elixir is a powerful technique that enhances the capabilities of Large Language Models (LLM) by incorporating relevant and up-to-date information. By leveraging document ingestion, chunking, embedding, vector database, retrieval, query processing, and generation, RAG enables LLMs to provide contextually accurate and useful responses without the need for retraining.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, I found understanding RAG systems to be very easy. However, managing the pipelines and moving this code into production will take further readings. Firstly, I’ll looking into metadata filtering because that allows us to find correct chunks further. Then, I’ll data ingestion as this is the step that allows us to represent the data better. i.e use data from tables, use data from pictures hence this is the most cruicial state in the RAG pipeline.&lt;&#x2F;p&gt;
&lt;p&gt;While building this “PrivateGPT”, I’ll use using Task.async, Genservers so that all processing can take place in the background. With Elixir excelling at background and concurrect tasks it is the best fit for this job.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=41107452&quot;&gt;Comments&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cloudflare Pages Build Bash Script for Zola</title>
        <published>2024-02-04T00:00:00+00:00</published>
        <updated>2024-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-cloudflare-pages-build-script/"/>
        <id>https://shapath.com.np/posts/til-cloudflare-pages-build-script/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-cloudflare-pages-build-script/">&lt;p&gt;Rather than using the predefied build commands of Cloudflare Pages, it is extremley handly to create a build script and call the script with &lt;code&gt;bash build.sh&lt;&#x2F;code&gt; from the build command. It gives you control over how pages are build in different branches.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;$CF_PAGES_BRANCH&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;$CF_PAGES_URL&lt;&#x2F;code&gt; are enviornment variables provided by Cloudflare at build time.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;#!&#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;echo &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Building Site Now&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;CF_PAGES_BRANCH&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;main&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;; then
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Run the &amp;quot;production&amp;quot; build
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;zola&lt;&#x2F;span&gt;&lt;span&gt; build --force
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;else
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;# Run the build  with drafts
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;zola&lt;&#x2F;span&gt;&lt;span&gt; build --drafts --force --base-url &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;CF_PAGES_URL
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;fi
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;pages&#x2F;how-to&#x2F;build-commands-branches&#x2F;&quot;&gt;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;pages&#x2F;how-to&#x2F;build-commands-branches&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pretty Print JSON Reponse in Bash</title>
        <published>2024-02-04T00:00:00+00:00</published>
        <updated>2024-02-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-format-json-response-in-bash/"/>
        <id>https://shapath.com.np/posts/til-format-json-response-in-bash/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-format-json-response-in-bash/">&lt;p&gt;Pipe output into &lt;code&gt;python -m json.tool&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span&gt; --request GET &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --url http:&#x2F;&#x2F;shapath.com.np&#x2F;posts&#x2F;til_format_json_response_in_bash.json &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           --header &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span&gt;           &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;python&lt;&#x2F;span&gt;&lt;span&gt; -m json.tool
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;## Pretty Printed Response
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&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;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;resposne&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;id&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;1&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;attributes&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;title&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;Pretty Printed&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;body&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;The shortest article. Ever.&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;created&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;2024-02-04T14:56:29.000Z&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;updated&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;2024-02-04T14:56:28.000Z&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;            },
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;relationships&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;author&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;id&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;42&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;links&amp;quot;
&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;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;included&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&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;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;type&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;links&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;id&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;42&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;attributes&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;link&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;example.com&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;domain&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;example.com&amp;quot;
&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 style=&quot;color:#88c0d0;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding Network Subnetting: IPv4</title>
        <published>2024-02-01T00:00:00+00:00</published>
        <updated>2024-02-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-understanding-network-subnetting/"/>
        <id>https://shapath.com.np/posts/til-understanding-network-subnetting/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-understanding-network-subnetting/">&lt;p&gt;Subnetting is the process of diving networks into smaller segments. A IPv4 address is a 32 bit number divided into 8 bit numbers.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;            10.10.10.10               ← (deminal)
&lt;&#x2F;span&gt;&lt;span&gt;                ↓
&lt;&#x2F;span&gt;&lt;span&gt;    10.       10.     10.      10     ← (decimal spaced)
&lt;&#x2F;span&gt;&lt;span&gt;                ↓
&lt;&#x2F;span&gt;&lt;span&gt;  00001010 00001010 00001010 00001010 ← (binary)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;examples&quot;&gt;Examples&lt;a class=&quot;zola-anchor&quot; href=&quot;#examples&quot; aria-label=&quot;Anchor link for: examples&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;A subnet of 255.255.255.255 or 10.10.10.0&#x2F;32 can have 1 address.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;11111111 11111111 11111111 11111111&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A subnet of 255.255.255.252 or 10.10.10.0&#x2F;30 can have 2 addresses.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;11111111 11111111 11111111 1111111&lt;ins&gt;0&lt;&#x2F;ins&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A subnet of 255.255.255.0 or 10.10.0.0&#x2F;24 can have 256 addresses.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;11111111 11111111 11111111 &lt;ins&gt;00000000&lt;&#x2F;ins&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A subnet of 255.255.254.0 or 10.10.0.0&#x2F;23 can have 512 addresses.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;11111111 11111111 1111111&lt;ins&gt;0&lt;&#x2F;ins&gt; &lt;ins&gt;00000000&lt;&#x2F;ins&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The difference between &lt;strong&gt;3&lt;&#x2F;strong&gt; &amp;amp; &lt;strong&gt;4&lt;&#x2F;strong&gt; is that the third part of the IPv4 can be 0 or 1, i.e 10.10.&lt;ins&gt;0&lt;&#x2F;ins&gt;.&lt;em&gt;[1-255]&lt;&#x2F;em&gt; or 10.10.&lt;ins&gt;1&lt;&#x2F;ins&gt;.&lt;em&gt;[1-255]&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.ripe.net&#x2F;about-us&#x2F;press-centre&#x2F;IPv4CIDRChart_2015.pdf&quot;&gt;https:&#x2F;&#x2F;www.ripe.net&#x2F;about-us&#x2F;press-centre&#x2F;IPv4CIDRChart_2015.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.aelius.com&#x2F;njh&#x2F;subnet_sheet.html&quot;&gt;https:&#x2F;&#x2F;www.aelius.com&#x2F;njh&#x2F;subnet_sheet.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;jodies.de&#x2F;ipcalc?host=10.10.10.1&amp;amp;mask1=21&quot;&gt;http:&#x2F;&#x2F;jodies.de&#x2F;ipcalc?host=10.10.10.1&amp;amp;mask1=21&lt;&#x2F;a&gt; - IP&#x2F;Subnet Calculator&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.calculator.net&#x2F;ip-subnet-calculator.html&quot;&gt;https:&#x2F;&#x2F;www.calculator.net&#x2F;ip-subnet-calculator.html&lt;&#x2F;a&gt; - IP&#x2F;Subnet Calculator&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>x86 Build in M1 Mac</title>
        <published>2024-01-31T00:00:00+00:00</published>
        <updated>2024-01-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-docker-x86-images-in-m1-mac/"/>
        <id>https://shapath.com.np/posts/til-docker-x86-images-in-m1-mac/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-docker-x86-images-in-m1-mac/">&lt;p&gt;Building docker images with the flag &lt;code&gt;--platform linux&#x2F;amd64&lt;&#x2F;code&gt; allows you to create x86 images using docker&lt;&#x2F;p&gt;
&lt;p&gt;Which platform am I on?&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;gt; gcc -dumpmachine
&lt;&#x2F;span&gt;&lt;span&gt;arm64-apple-darwin23.2.0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;let-s-run-an-image-to-enter-the-x86-world&quot;&gt;Let’s run an image to enter the x86 world&lt;a class=&quot;zola-anchor&quot; href=&quot;#let-s-run-an-image-to-enter-the-x86-world&quot; aria-label=&quot;Anchor link for: let-s-run-an-image-to-enter-the-x86-world&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; docker &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt; -it --platform&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;linux&#x2F;amd64 gcc:13.2.0 &#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;inside&lt;&#x2F;span&gt;&lt;span&gt; docker container)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; gcc -dumpmachine
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;x86_64-linux-gnu
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;when-to-use-this&quot;&gt;When to use this?&lt;a class=&quot;zola-anchor&quot; href=&quot;#when-to-use-this&quot; aria-label=&quot;Anchor link for: when-to-use-this&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;This is helpful to build cross platform images. i.e. in Elixir you can create a binary file with &lt;code&gt;mix release&lt;&#x2F;code&gt; however it only targets the current platform target triple. As my server runs on &lt;code&gt;linux&#x2F;amd64&lt;&#x2F;code&gt; I would have to build the code again rather than just copying over the binary file. Hence, I use this script to build the binary for the x86 platform and copy over the binary file only.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SSH&#x2F;Telnet into Nokia G-2425G-A</title>
        <published>2024-01-26T00:00:00+00:00</published>
        <updated>2024-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-ssh-telnet-into-nokia-g-2425-g-a/"/>
        <id>https://shapath.com.np/posts/til-ssh-telnet-into-nokia-g-2425-g-a/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-ssh-telnet-into-nokia-g-2425-g-a/">&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Device Infromation:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Device Name G-2425G-A
&lt;&#x2F;span&gt;&lt;span&gt;Vendor Nokia
&lt;&#x2F;span&gt;&lt;span&gt;Boot Version U-Boot Dec-31-2016--12:00:00
&lt;&#x2F;span&gt;&lt;span&gt;Router IP https:&#x2F;&#x2F;192.168.1.254
&lt;&#x2F;span&gt;&lt;span&gt;Chipset MTK7528
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Default login for SSH, Telnet CLI, and Web GUI AdminGPON &#x2F; ALC#FGU. However this can be changed by ISP by using &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;TR-069&quot;&gt;TR069&lt;&#x2F;a&gt; after connecting the fiber cable.&lt;&#x2F;p&gt;
&lt;p&gt;There is also another user userAdmin &#x2F; userAdmin.&lt;&#x2F;p&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;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Reset the router so that it is possible to use the AdminGPON user. Another way is to extract the configuration after ISP has setup the modem router using TR-069. (contact me for further info – see secure notes on phone)&lt;&#x2F;li&gt;
&lt;li&gt;Extract the cfg file using &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;thedroidgeek&#x2F;80c379aa43b71015d71da130f85a435a&quot;&gt;nokia-router-cfg-tool.py&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Enable TelnetSSHAccount. in the extracted XML file using the script above. Set username as &lt;code&gt;ONTUSER&lt;&#x2F;code&gt; and password as &lt;code&gt;OYdLWUVDdKQTPaCIeTqniA==&lt;&#x2F;code&gt; which equates to
&lt;code&gt;admin&lt;&#x2F;code&gt;. If using another username, root access might not be possible.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;TelnetSshAccount. &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;TelnetSshAccount&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;staticObject&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;Enable &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RW&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;boolean&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;true&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;lt;&#x2F;Enable&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;UserName &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ml&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;64&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RW&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;string&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;ONTUSER&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;lt;&#x2F;UserName&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;Password &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ml&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;64&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RW&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;string&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;2NtCuV9+tykYlr4EmoJFxg==&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ealgo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;ab&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;lt;&#x2F;Password&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;&#x2F;TelnetSshAccount.&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Set LimitAccount_ONTUSER to &lt;code&gt;false&lt;&#x2F;code&gt;. Further, &lt;code&gt;ONTLOCK&lt;&#x2F;code&gt; (search the XML file) might also be needed to be set to &lt;code&gt;false&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;LimitAccount_ONTUSER &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RW&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;boolean&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;false&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;lt;&#x2F;LimitAccount_ONTUSER&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;X_ASB_COM_ONTLOCK &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;boolean&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;v&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;false&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;dv&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;false&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;RW&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt;&amp;lt;&#x2F;X_ASB_COM_ONTLOCK&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Repack the xml file using &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;thedroidgeek&#x2F;80c379aa43b71015d71da130f85a435a&quot;&gt;nokia-router-cfg-tool.py&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Upload the new cfg file into the router. You might want to use a LAN connection for this, but it has been working fine over WLAN for me.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 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;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;After logging to the router portal, greyed-out (disabled) settings can be changed using the inspect element and removing the disabled prop from html.
&lt;img src=&quot;&#x2F;posts&#x2F;til_ssh-telnet-access-disabled-fields-on-nokia-gpon.png&quot; alt=&quot;remove disabled prop from html tag&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;0x41.cf&#x2F;reversing&#x2F;2019&#x2F;10&#x2F;08&#x2F;unlocking-nokia-g240wa.html&quot;&gt;https:&#x2F;&#x2F;0x41.cf&#x2F;reversing&#x2F;2019&#x2F;10&#x2F;08&#x2F;unlocking-nokia-g240wa.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;blog.fractal-reality.tech&#x2F;2020&#x2F;12&#x2F;26&#x2F;rooting-airtel-router&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.fractal-reality.tech&#x2F;2020&#x2F;12&#x2F;26&#x2F;rooting-airtel-router&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;thedroidgeek&#x2F;80c379aa43b71015d71da130f85a435a&quot;&gt;https:&#x2F;&#x2F;gist.github.com&#x2F;thedroidgeek&#x2F;80c379aa43b71015d71da130f85a435a&lt;&#x2F;a&gt; (See comments as well)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;broadbandforum.co&#x2F;threads&#x2F;nokia-g-140w-f-bridge-mode.199535&#x2F;post-1533663&quot;&gt;https:&#x2F;&#x2F;broadbandforum.co&#x2F;threads&#x2F;nokia-g-140w-f-bridge-mode.199535&#x2F;post-1533663&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;codeanit&#x2F;til&#x2F;issues&#x2F;61&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;codeanit&#x2F;til&#x2F;issues&#x2F;61&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;posts&#x2F;til_ssh-telnet-nokia-router-cfg-tool.py&quot;&gt;nokia-router-cfg-tool.py&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reversing A List</title>
        <published>2024-01-24T00:00:00+00:00</published>
        <updated>2024-01-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-reversing-a-list/"/>
        <id>https://shapath.com.np/posts/til-reversing-a-list/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-reversing-a-list/">&lt;p&gt;To efficiently work with and &lt;em&gt;transform&lt;&#x2F;em&gt; lists in Elixir, you will likely
need utilize a list reversing function from time to time. Your best bet is
to reach for the Erlang implementation which is available as part of the
&lt;code&gt;lists&lt;&#x2F;code&gt; module.&lt;&#x2F;p&gt;
&lt;p&gt;Here are a couple examples of how to use it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;:lists&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reverse([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;:lists&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reverse([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:a&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;what&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;what&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;:a&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note: though I said “&lt;em&gt;transform&lt;&#x2F;em&gt; lists” above, what is actually going on is
that a new version of the list representing my transformation is being
created, per Elixir’s functional nature.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jbranchaud&#x2F;til&#x2F;blob&#x2F;c7bea5aa7818767aef1915e3abe887f661df45cd&#x2F;elixir&#x2F;reversing-a-list.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;jbranchaud&#x2F;til&#x2F;blob&#x2F;c7bea5aa7818767aef1915e3abe887f661df45cd&#x2F;elixir&#x2F;reversing-a-list.md&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Kill Database Sessions</title>
        <published>2024-01-21T00:00:00+00:00</published>
        <updated>2024-01-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-kill-database-sessions/"/>
        <id>https://shapath.com.np/posts/til-kill-database-sessions/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-kill-database-sessions/">&lt;p&gt;The following snippet kills all connected database sessions except the current connected connection.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sql&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-sql &quot;&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;SELECT
&lt;&#x2F;span&gt;&lt;span&gt;  pg_terminate_backend(pid)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;FROM
&lt;&#x2F;span&gt;&lt;span&gt;  pg_stat_activity
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;WHERE
&lt;&#x2F;span&gt;&lt;span&gt;  pid &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; pg_backend_pid()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;AND&lt;&#x2F;span&gt;&lt;span&gt; datname &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;database_name&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get Git Details From Elixir</title>
        <published>2024-01-20T00:00:00+00:00</published>
        <updated>2024-01-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-get-git-commit-details/"/>
        <id>https://shapath.com.np/posts/til-get-git-commit-details/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-get-git-commit-details/">&lt;p&gt;The following snippet allows you to extract the SHA1 of the git commit from within elixir. It is useful to attach the SHA1 to your release or code so that if therea are any issues you can quickly checkout the commit and look into it.&lt;&#x2F;p&gt;
&lt;p&gt;You can also get the branch name if required.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;elixir&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-elixir &quot;&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;git_commit_sha&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;System&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cmd(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;git&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;rev-parse&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;--short&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;HEAD&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; elem(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;trim()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;git_branch_name&lt;&#x2F;span&gt;&lt;span&gt;() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;do
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;System&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cmd(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;git&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;rev-parse&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;--abbrev-ref&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;quot;HEAD&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; elem(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;|&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;trim()
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;end
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Find PostgreSQL Data Directory</title>
        <published>2024-01-19T00:00:00+00:00</published>
        <updated>2024-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-postgresql-data-directory/"/>
        <id>https://shapath.com.np/posts/til-postgresql-data-directory/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-postgresql-data-directory/">&lt;p&gt;The following snippet finds where the PostgreSQL database directory is located.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;psql&lt;&#x2F;span&gt;&lt;span&gt; -U postgres -c &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;SHOW data_directory&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Find PostgreSQL Config Location</title>
        <published>2024-01-18T00:00:00+00:00</published>
        <updated>2024-01-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-postgresql-config-file/"/>
        <id>https://shapath.com.np/posts/til-postgresql-config-file/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-postgresql-config-file/">&lt;p&gt;The following snippet finds where the PostgreSQL config file is located.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;psql&lt;&#x2F;span&gt;&lt;span&gt; -U postgres -c &lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&amp;#39;SHOW config_file&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Github+1 Workflow</title>
        <published>2024-01-11T00:00:00+00:00</published>
        <updated>2024-01-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/github-1-workflow/"/>
        <id>https://shapath.com.np/posts/github-1-workflow/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/github-1-workflow/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE: A &lt;em&gt;comprehensive&lt;&#x2F;em&gt; read&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This post is a part of a document created for my team at Weber State Univeristy to gain an indepth understanding of Git — its abundant usefulness in a team setup.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Teams use several types git models. Git-Flow being one of the most polular team workflows around. However, since the rise of continious integration (CI). Github Flow has slowly started to gain its prominence. Github Flow is a lightweight branched based workflow for Git. Github Flow only contains one main branch &lt;code&gt;master&lt;&#x2F;code&gt; and feature branches are created from it. However, this model uses two major branches &lt;code&gt;master&lt;&#x2F;code&gt; and &lt;code&gt;develop&lt;&#x2F;code&gt;. Hence, the feature branches are created from &lt;code&gt;develop&lt;&#x2F;code&gt; branch. And the master is a stable state of the program. All changes and experiments should be made on &lt;code&gt;feature&lt;&#x2F;code&gt; branches so that code is reviewed by other people in the team before it is merged into &lt;code&gt;develop&lt;&#x2F;code&gt;.  Your feature branches should be verbosely descriptive so that other people in the team can clearly see what is being worked on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;working-with-branches&quot;&gt;Working with Branches&lt;a class=&quot;zola-anchor&quot; href=&quot;#working-with-branches&quot; aria-label=&quot;Anchor link for: working-with-branches&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;A new branch is created from the develop branch &lt;code&gt;git checkout -b feature&#x2F;{descriptive-name}&lt;&#x2F;code&gt; to make newer changes to the code.&lt;&#x2F;p&gt;
&lt;p&gt;If you are working on a &lt;code&gt;feature&lt;&#x2F;code&gt;, the branch should have the name &lt;code&gt;feature&#x2F;{descriptive-name}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you are working on a &lt;code&gt;issue&lt;&#x2F;code&gt;. the branch should have the name &lt;code&gt;issue&#x2F;{descriptive-name}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you are working on a &lt;code&gt;fix&lt;&#x2F;code&gt;. the branch should have the name &lt;code&gt;fix&#x2F;{descriptive-name}&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;commits&quot;&gt;Commits&lt;a class=&quot;zola-anchor&quot; href=&quot;#commits&quot; aria-label=&quot;Anchor link for: commits&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Commits should be made after logical changes, additionally, make sure that logical units of code.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git add -A&lt;&#x2F;code&gt; or &lt;code&gt;git add -A hello.py&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;followed by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git commit -m &quot;Added hello.py&quot;&lt;&#x2F;code&gt; or &lt;code&gt;git commit&lt;&#x2F;code&gt; and an interactive terminal will allow you to write your commit message.&lt;&#x2F;p&gt;
&lt;p&gt;These commits messages are useful because it allows the modification of code to be tracked. Furthermore, each commit is a seperate unit of change. Hence, if a bug is found, an easy rollback is possible.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;By writing clear commits messages, you can make it easier for other people to follow the changes
in your code and provide better feedback.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;the-art-of-the-commit-message&quot;&gt;The Art of the Commit Message&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-art-of-the-commit-message&quot; aria-label=&quot;Anchor link for: the-art-of-the-commit-message&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;We use a strict style for all of our commit messages. The style we use helps
ensure that our commits stay small and are easy to browse.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The Layout&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;&amp;lt;type&amp;gt;: &amp;lt;subject&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;body&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;footer&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;The Title (the first line)&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The title consists of the &lt;code&gt;&amp;lt;type&amp;gt;&lt;&#x2F;code&gt; and the &lt;code&gt;&amp;lt;subject&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Allowed Values for &lt;code&gt;&amp;lt;type&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;feat&lt;&#x2F;strong&gt; (new feature)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;fix&lt;&#x2F;strong&gt; (bug fix)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;docs&lt;&#x2F;strong&gt; (changes to documentation)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;style&lt;&#x2F;strong&gt; (formatting, missing semi colons, etc; no code change)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;refactor&lt;&#x2F;strong&gt; (refactoring production code)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;test&lt;&#x2F;strong&gt; (adding missing tests, refactoring tests; no production code change)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;chore&lt;&#x2F;strong&gt; (updating grunt tasks etc; no production code change)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Subject&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;365git.tumblr.com&#x2F;post&#x2F;3308646748&#x2F;writing-git-commit-messages&quot;&gt;imperative tone&lt;&#x2F;a&gt; is also helpful in conveying what a commit does,
rather than what it did. For example, use &lt;strong&gt;change&lt;&#x2F;strong&gt;, not &lt;em&gt;changed&lt;&#x2F;em&gt; or
&lt;em&gt;changes&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The Body&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The body of the commit message should use a style similar to the one proposed
in this &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;tbaggery.com&#x2F;2008&#x2F;04&#x2F;19&#x2F;a-note-about-git-commit-messages.html&quot;&gt;article by tpope&lt;&#x2F;a&gt;. The body, just like the subject, should use
an imperative tone.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The Footer&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here you can reference issues and pull-requests that relate to your commit, like so:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;closes #125 or closes #123, #245, #992
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Breaking Change&lt;&#x2F;strong&gt;
All breaking changes have to be mentioned in footer with the description of the change, justification and migration notes.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;BREAKING&lt;&#x2F;span&gt;&lt;span&gt; CHANGE:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;port-runner&lt;&#x2F;span&gt;&lt;span&gt;` command line option has changed to `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;runner-port&lt;&#x2F;span&gt;&lt;span&gt;`, so that it is
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;consistent&lt;&#x2F;span&gt;&lt;span&gt; with the configuration file syntax.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;To&lt;&#x2F;span&gt;&lt;span&gt; migrate your project, change all the commands, where you use `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;--port-runner&lt;&#x2F;span&gt;&lt;span&gt;`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;to &lt;&#x2F;span&gt;&lt;span&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;--runner-port&lt;&#x2F;span&gt;&lt;span&gt;`.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can see the &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;help.github.com&#x2F;articles&#x2F;closing-issues-via-commit-messages&#x2F;&quot;&gt;official Github doc&lt;&#x2F;a&gt; for all the keywords to close issues and pull-requests.&lt;&#x2F;p&gt;
&lt;p&gt;Never forget this standard! Set your commit &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sparkbox&#x2F;standard&#x2F;blob&#x2F;babdc546216e07fef4bad58a91d69a9bc11f48a7&#x2F;style&#x2F;git&#x2F;.gitmessage&quot;&gt;message template&lt;&#x2F;a&gt; to this example, by running:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git config --global commit.template &amp;quot;path&#x2F;to&#x2F;.gitmessage&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# Drop the `--global` flag to only use this template for one (this) repository.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Protip: Do a &lt;code&gt;rebase&lt;&#x2F;code&gt; and an &lt;code&gt;interactive commit&lt;&#x2F;code&gt; (simply, &lt;code&gt;git commit&lt;&#x2F;code&gt;) when you are ready to open a pull request. While working, locally, you do not need to follow this standard.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Read more about writing better commit messages &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;karma-runner.github.io&#x2F;1.0&#x2F;dev&#x2F;git-commit-msg.html&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;This section &lt;strong&gt;completely&lt;&#x2F;strong&gt; inspired by &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y&#x2F;edit#&quot;&gt;Angular&lt;&#x2F;a&gt;, &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;karma-runner.github.io&#x2F;0.8&#x2F;dev&#x2F;git-commit-msg.html&quot;&gt;Karma’s&lt;&#x2F;a&gt; and &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sparkbox&#x2F;standard&#x2F;blob&#x2F;babdc546216e07fef4bad58a91d69a9bc11f48a7&#x2F;style&#x2F;git&#x2F;README.md&quot;&gt;Sparkbox&lt;&#x2F;a&gt; commit style.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pull-requests&quot;&gt;Pull Requests&lt;a class=&quot;zola-anchor&quot; href=&quot;#pull-requests&quot; aria-label=&quot;Anchor link for: pull-requests&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Pull requests let you tell others about changes you’ve pushed to a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before the changes are merged into the repository.&lt;&#x2F;p&gt;
&lt;p&gt;After you have created your feature branch, and made commits to it. It is now time to create a pull request on Github. The &lt;code&gt;develop&lt;&#x2F;code&gt; branch currently and the develop branch you checkouted out your current working branch may (probably will) be different because other people in the team may have made changes or sent pull request to the project.  Hence, make sure the current branch you are working on is always upto date with the &lt;code&gt;develop&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git checkout develop &amp;amp;&amp;amp; git pull &amp;amp;&amp;amp; git checkout - &amp;amp;&amp;amp; git rebase develop&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;or simply&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git pull --rebase origin develop&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Again, make sure you title the Pull Requests title verbosely so that team members
can clear understand what is being worked on.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Git is really flexible about merging conflicts, however, you’ll probably see some merge errors when you are working in the same area (lines) as the develop branch, which is evolving constantly. The error message will verbosely state the merge conflicts. Henceforth, you should merge these changes into your current working branch. Do this often so that, there isn’t a large numeber of merge errors at once.&lt;&#x2F;p&gt;
&lt;p&gt;When there is a merge conflict, &lt;code&gt;git rebase --continue&lt;&#x2F;code&gt; will allow you to integrate newer changes from the develop branch into your current working branch. After these changes are made you will need to add these changes into git with &lt;code&gt;git add file.name&lt;&#x2F;code&gt;. The commit is handled by the rebasing process therefore &lt;code&gt;git commit&lt;&#x2F;code&gt; is not required.&lt;&#x2F;p&gt;
&lt;p&gt;Consider reading, &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;blog&#x2F;1943-how-to-write-the-perfect-pull-request&quot;&gt;How to Write the Perfect Pull Request&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;accepting-pull-requests&quot;&gt;Accepting Pull Requests&lt;a class=&quot;zola-anchor&quot; href=&quot;#accepting-pull-requests&quot; aria-label=&quot;Anchor link for: accepting-pull-requests&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Each pull request should only have one commit, if you have multiple commits, espcially if they are meaning less, i.e. missed an comma or added file. These commits do not provide any additional value to the code therefore rebase these meaningless commits into one commit using rebase. Squash these commits.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure you are on your current working branch.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git log&lt;&#x2F;code&gt; Will help you see the commits you have made.
&lt;code&gt;git rebase -i HEAD~4&lt;&#x2F;code&gt; Selects the last four commits you made. This snippet only starts the process of rebasing. You do not have to squash all your commits. These can be picked on the followup screen.&lt;&#x2F;p&gt;
&lt;p&gt;The available rebase options are;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# p, pick = use commit
&lt;&#x2F;span&gt;&lt;span&gt;# r, reword = use commit, but edit the commit message
&lt;&#x2F;span&gt;&lt;span&gt;# e, edit = use commit, but stop for amending
&lt;&#x2F;span&gt;&lt;span&gt;# s, squash = use commit, but meld into previous commit
&lt;&#x2F;span&gt;&lt;span&gt;# f, fixup = like &amp;quot;squash&amp;quot;, but discard this commit&amp;#39;s log message
&lt;&#x2F;span&gt;&lt;span&gt;# x, exec = run command (the rest of the line) using shell
&lt;&#x2F;span&gt;&lt;span&gt;# d, drop = remove commit
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The following snippet shows commit &lt;code&gt;6340aaa&lt;&#x2F;code&gt; &lt;code&gt;ebfd367&lt;&#x2F;code&gt; &lt;code&gt;30e0ccb&lt;&#x2F;code&gt; is being squashed into &lt;code&gt;01d1124&lt;&#x2F;code&gt; commit.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;pick 01d1124 Adding functional print module
&lt;&#x2F;span&gt;&lt;span&gt;squash 6340aaa Missed a simple function
&lt;&#x2F;span&gt;&lt;span&gt;squash ebfd367 Jekyll has become self-aware.
&lt;&#x2F;span&gt;&lt;span&gt;squash 30e0ccb Changed the line from a to b.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After you have squashed multiple commits into one, because of change in git history.A force push, &lt;code&gt;git push -f&lt;&#x2F;code&gt; is required to send these changes to upstream (remote). Since you are working on your own branch, this is allowed.&lt;&#x2F;p&gt;
&lt;p&gt;The reviewer or the team lead will assign a team member to merge these changes into the develop branch. This is usually going to be the same person who sent the pull request.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can only squash newer commits to an older one. However, you can ammend the old commit message by putting a &lt;code&gt;reword&lt;&#x2F;code&gt; instead of &lt;code&gt;pick&lt;&#x2F;code&gt; while rebasing. Also, if you are squshing commits using id’s, choose the following commit id of the commit you want to rebase.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h5 id=&quot;wip-pull-requests&quot;&gt;[WIP] Pull Requests&lt;a class=&quot;zola-anchor&quot; href=&quot;#wip-pull-requests&quot; aria-label=&quot;Anchor link for: wip-pull-requests&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h5&gt;
&lt;p&gt;You are welcome to open pull requests even though you have not completed a feature or a issue so that team members can review your code from the very begining. No other team member will “touch” your &lt;code&gt;branch&lt;&#x2F;code&gt; unless you explicitly ask to do so. Make sure you label this clearly with a [WIP] tag in the beginning of the name so that team members can easily filter these pull requests unless you explitcly ask for help.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Be careful while force pushing into shared branches. As this changes the history, make sure the collabrates know of this by commeting on the pull requests. A better way is to not rebase till the feature is fully ready to merge. The latter is preferred.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;merging-current-branch-into-develop&quot;&gt;Merging Current Branch into Develop&lt;a class=&quot;zola-anchor&quot; href=&quot;#merging-current-branch-into-develop&quot; aria-label=&quot;Anchor link for: merging-current-branch-into-develop&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h3&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;A team should usually only have ONE or very few number of people merging the pull requests.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After the pull request has been approved, you can merge these changes directly from Github or if there are merge conflicts, locally on your computer.&lt;&#x2F;p&gt;
&lt;p&gt;Naming convention for merge commit: Merge: feature&#x2F;{branch} via Pull Request #{number}
Example, Merge: feature&#x2F;database via Pull Request #1&lt;&#x2F;p&gt;
&lt;p&gt;Make sure that the pull request number is added on to the merge commit so that other team members can easily reference the changes and the comments for this merge.&lt;&#x2F;p&gt;
&lt;p&gt;On Github, make sure that you merge your changes with &lt;code&gt;create a merge commit&lt;&#x2F;code&gt; so that the history of your branch will be moved over to the develop branch.&lt;&#x2F;p&gt;
&lt;p&gt;On your local computer, you will follow these steps,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Step 1&lt;&#x2F;strong&gt;: From your project repository, bring in the changes and test.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git fetch origin
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;# do this step if you are assigned another branch that you have not made changes to
&lt;&#x2F;span&gt;&lt;span&gt;# otherwise this step should already be done when you pushed your branch upstream
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;git checkout -b feature&#x2F;{branch} origin&#x2F;feature&#x2F;{branch}
&lt;&#x2F;span&gt;&lt;span&gt;git merge develop
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Step 2&lt;&#x2F;strong&gt;: Merge the changes and update on GitHub.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git checkout develop
&lt;&#x2F;span&gt;&lt;span&gt;git merge --no-ff feature&#x2F;{branch}
&lt;&#x2F;span&gt;&lt;span&gt;git push origin develop
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note: The &lt;code&gt;--no-ff&lt;&#x2F;code&gt; is important so that the history of your branch will be moved over to the develop branch.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If your branch name is not meaningful, the Team Lead will ask you to rename your branch, as you do this, you will need to create a new pull request. Rename branch using &lt;code&gt;git branch -m feature&#x2F;{new-name}&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;stashing-commits&quot;&gt;Stashing Commits&lt;a class=&quot;zola-anchor&quot; href=&quot;#stashing-commits&quot; aria-label=&quot;Anchor link for: stashing-commits&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Often, when working on a project, you would want to switch branches when you want to work on something else for a bit or there is a issue you need to fix urgently. And you do no want to commit half done work because someone else is reviewing your code. The answer to this issue is &lt;code&gt;git stash&lt;&#x2F;code&gt;. Stash takes the current state of your working directory (the changes you made) and saves in a stack.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git stash
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;git stash list
&lt;&#x2F;span&gt;&lt;span&gt;  stash@{0}: WIP on feature&#x2F;changes: 043d356 added the controller
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this, you can switch branches and work on something different. After a while, when you come back to finish the feature with do &lt;code&gt;git stash apply&lt;&#x2F;code&gt; to reapply the changes you made to the working directory.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have made multiple items on your stash, do git stash list to see which one you want to reapply.
Then, reapply a particular stash using &lt;code&gt;git stash apply stash@{0}&lt;&#x2F;code&gt;
Otherwise, since the stash is stored in a stack it pop outs the last inserted item.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;reverting-commits&quot;&gt;Reverting Commits&lt;a class=&quot;zola-anchor&quot; href=&quot;#reverting-commits&quot; aria-label=&quot;Anchor link for: reverting-commits&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This usage of git reset is a simple way to undo changes that haven’t been shared with anyone else. It’s your go-to command when you’ve started working on a feature and find yourself thinking, “Oh crap, what am I doing? I should just start over.” - &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.atlassian.com&#x2F;git&#x2F;tutorials&#x2F;resetting-checking-out-and-reverting&quot;&gt;via Atlassian&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can reset your commits using the &lt;code&gt;--hard&lt;&#x2F;code&gt; or the &lt;code&gt;--mixed flag&lt;&#x2F;code&gt;. The latter is default.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git reset --hard SHA_ID or HEAD~1
&lt;&#x2F;span&gt;&lt;span&gt;git reset --mixed SHA_ID or HEAD~1
&lt;&#x2F;span&gt;&lt;span&gt;git reset HEAD~1 # defaults to git reset --mixed
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;--hard&lt;&#x2F;code&gt; takes the commits and &lt;strong&gt;modifies your directory&lt;&#x2F;strong&gt; so that your code matches the commit exactly. All changes will be removed.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;--mixed&lt;&#x2F;code&gt; flag takes the commits and unstages changes after this commit. You will still have the &lt;strong&gt;changes in your working directory&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Usually, use the latter, and you can stash your changes so that you still have access to the changes if you need them later. If you want to start over and want a clean directory use &lt;code&gt;--hard&lt;&#x2F;code&gt; reset.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tagging-commits&quot;&gt;Tagging Commits&lt;a class=&quot;zola-anchor&quot; href=&quot;#tagging-commits&quot; aria-label=&quot;Anchor link for: tagging-commits&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Git tags are used to indentify stable release. The use of schematic versioning for tags allows for version numbers and the way they change convey.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;Given a version number MAJOR.MINOR.PATCH, increment the:
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;MAJOR version when you make incompatible API changes,
&lt;&#x2F;span&gt;&lt;span&gt;MINOR version when you add functionality in a backwards-compatible manner, and
&lt;&#x2F;span&gt;&lt;span&gt;PATCH version when you make backwards-compatible bug fixes.
&lt;&#x2F;span&gt;&lt;span&gt;Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;semver.org&quot;&gt;Schematic Versioning&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A simple &lt;code&gt;git tag [version]&lt;&#x2F;code&gt; will tag the commit you are currently on.
To remove the tag, &lt;code&gt;git tag -d [version]&lt;&#x2F;code&gt; will remove the tag.&lt;&#x2F;p&gt;
&lt;p&gt;You can also annotate and attach a message a tag so that it is descriptive.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git tag -a -m &quot;Release Tag Message 1.0&quot; v1.0&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Don’t forget you need to push your tags seperately with &lt;code&gt;git push --tags&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Team Lead is responsible for chronially tagging commits using Schematic Versioning. A team member seldom tags a commit.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;blaming-others&quot;&gt;Blaming Others&lt;a class=&quot;zola-anchor&quot; href=&quot;#blaming-others&quot; aria-label=&quot;Anchor link for: blaming-others&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Git blame searches the commit history and allows you to see who is the last person who modified the particular line of code.&lt;&#x2F;p&gt;
&lt;p&gt;You can do this simply with &lt;code&gt;git blame file.name&lt;&#x2F;code&gt;
Additionally, you can search specific line numbers with &lt;code&gt;git blame file.name -L 32,45&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If you want to go back and see how and who has changed the file use the following snippet.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git log -p -M --follow --stat -- file.name
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If there are problems in the code, do a &lt;code&gt;git blame&lt;&#x2F;code&gt;, and create a issue on Github and mention the team member in the issue so that the person can get back to you before making changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-few-git-tips-and-tricks&quot;&gt;A few Git tips and tricks&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-few-git-tips-and-tricks&quot; aria-label=&quot;Anchor link for: a-few-git-tips-and-tricks&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Use aliases for git, this various git commands in a few keystrokes.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Also consider using a bash prompt (PS1) that allows you to see which branch you are working on.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;I know using Github GUI is easy however, it only harnesses a mere potential of Git. Therefore start loving using git via command-line and leave the GUI behind.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Make sure to set your name in git so that when you push, we exactly know who the team member is&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;git config --global user.name &amp;quot;Shap Guy&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;git config --global user.email &amp;quot;email@domain.com&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Drop the &lt;code&gt;--global&lt;&#x2F;code&gt; flag if you only want to change your email for this specific repository. Make sure you use your Weber email so that your personal email is not attached to commits.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Make sure you change the default commit message template so that it follows the project standards.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;git push -f&lt;&#x2F;code&gt; is &lt;strong&gt;only allowed&lt;&#x2F;strong&gt; on branches &lt;em&gt;you&lt;&#x2F;em&gt; are working on. Changing the history, in any way, of the repo will be frowned upon.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;It is better to use &lt;code&gt;git add -A&lt;&#x2F;code&gt; rather than &lt;code&gt;git add .&lt;&#x2F;code&gt; because the first one automatically tracks file deletions in the working directory.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Git’s policy is commit often, rebase later, push once.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;additional-resources&quot;&gt;Additional Resources&lt;a class=&quot;zola-anchor&quot; href=&quot;#additional-resources&quot; aria-label=&quot;Anchor link for: additional-resources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.atlassian.com&#x2F;git&#x2F;tutorials&quot;&gt;Become a Git Guru&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;git-tips&#x2F;tips&quot;&gt;Most commonly used Git Tips and Tricks&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;nuclearsquid.com&#x2F;writings&#x2F;git-tricks-tips-workflows&#x2F;&quot;&gt;Git Workflow Tips&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;about.gitlab.com&#x2F;2016&#x2F;12&#x2F;08&#x2F;git-tips-and-tricks&#x2F;&quot;&gt;GitLab Tips and Tricks&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get Your Public IP Address</title>
        <published>2024-01-04T00:00:00+00:00</published>
        <updated>2024-01-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/til-get-your-public-ip/"/>
        <id>https://shapath.com.np/posts/til-get-your-public-ip/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/til-get-your-public-ip/">&lt;p&gt;If you’re trying to figure out what your current public IP address is, there is
a server you can ask. It is a server running at &lt;code&gt;https:&#x2F;&#x2F;ifconfig.me&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can visit that URL in your browser to find your IP address and some other
User Agent&#x2F;Request details. The site also mentions several &lt;code&gt;cURL&lt;&#x2F;code&gt; commands you
can run to get these details in your terminal.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl -4 https:&#x2F;&#x2F;api64.ipify.org
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl -6 https:&#x2F;&#x2F;api64.ipify.org
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To get further information go to &lt;code&gt;ifconfig.me&#x2F;ip&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;See &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;ifconfig.me&quot;&gt;ifconfig.me&lt;&#x2F;a&gt; for more details.
See &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.ipify.org&quot;&gt;https:&#x2F;&#x2F;www.ipify.org&lt;&#x2F;a&gt; for more details.
See &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;wtfismyip.com&quot;&gt;https:&#x2F;&#x2F;wtfismyip.com&lt;&#x2F;a&gt; to get IPv4 &amp;amp; IPv6 IP on the same page.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.mfitzp.com&#x2F;article&#x2F;use-ifconfigme-to-return-your-ip-and-host&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;jbranchaud&#x2F;til&#x2F;blob&#x2F;c7bea5aa7818767aef1915e3abe887f661df45cd&#x2F;workflow&#x2F;get-your-public-ip-address.md&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.ipify.org&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Automating Blog Hosting With Ansible</title>
        <published>2023-12-12T00:00:00+00:00</published>
        <updated>2023-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/automating-blog-hosting-with-ansible/"/>
        <id>https://shapath.com.np/posts/automating-blog-hosting-with-ansible/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/automating-blog-hosting-with-ansible/">&lt;blockquote&gt;
&lt;p&gt;This blog post is a hands down tutorial on &lt;code&gt;provisioning&lt;&#x2F;code&gt; a server by hosting a blog using Git and nginx with Ansible.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Ansible is a configuration management system. Ansible by default uses the SSH protocol to manage machines. There are other configuration tools like Puppet and Chef, however these require you to install a small piece of software on the client server. Hence, my preference to Ansible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-ansible&quot;&gt;Installing Ansible&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-ansible&quot; aria-label=&quot;Anchor link for: installing-ansible&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We only need to install Ansible on the local computer. However make sure the server has &lt;code&gt;Python 2.7&lt;&#x2F;code&gt; installed.&lt;&#x2F;p&gt;
&lt;p&gt;If you have &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;brew.sh&quot;&gt;brew&lt;&#x2F;a&gt; installed on a Mac OS. You can simply do&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ brew install ansible
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For Ubuntu,&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;$ sudo apt-get install software-properties-common
&lt;&#x2F;span&gt;&lt;span&gt;$ sudo apt-add-repository ppa:ansible&#x2F;ansible
&lt;&#x2F;span&gt;&lt;span&gt;$ sudo apt-get update
&lt;&#x2F;span&gt;&lt;span&gt;$ sudo apt-get install ansible
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Please refer to &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;docs.ansible.com&#x2F;ansible&#x2F;latest&#x2F;installation_guide&#x2F;index.html&quot;&gt;Ansible Installation Docs&lt;&#x2F;a&gt; to install on more OS’s&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ansible-basics&quot;&gt;Ansible Basics&lt;a class=&quot;zola-anchor&quot; href=&quot;#ansible-basics&quot; aria-label=&quot;Anchor link for: ansible-basics&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;There are two ways you can use Ansible depending on your use case. Firstly, use can use Ansible like &lt;code&gt;bash&lt;&#x2F;code&gt; scripts. These will be lists of &lt;code&gt;tasks&lt;&#x2F;code&gt; that you use to provision the server.&lt;&#x2F;p&gt;
&lt;p&gt;Secondly, we can use Ansible to create &lt;code&gt;roles&lt;&#x2F;code&gt;. Ansible uses roles to seperate it’s blocks of tasks. This allows you to copy blocks from one playbook to another without any hassle. A &lt;code&gt;playbook&lt;&#x2F;code&gt; in essence is how your tasks and roles are executed. Addtionally, it can be uploaded into &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;galaxy.ansible.com&quot;&gt;Ansible Galaxy&lt;&#x2F;a&gt; for other people to use it.&lt;&#x2F;p&gt;
&lt;p&gt;An Ansible Role needs to have a specific directory structure. You can manually create this directory structure; an easier way is to use &lt;code&gt;ansible-galaxy init newrole&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This command creates the follwing directory strcuture.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;├── defaults
&lt;&#x2F;span&gt;&lt;span&gt;│   └── main.yml
&lt;&#x2F;span&gt;&lt;span&gt;├── files
&lt;&#x2F;span&gt;&lt;span&gt;├── handlers
&lt;&#x2F;span&gt;&lt;span&gt;│   └── main.yml
&lt;&#x2F;span&gt;&lt;span&gt;├── meta
&lt;&#x2F;span&gt;&lt;span&gt;│   └── main.yml
&lt;&#x2F;span&gt;&lt;span&gt;├── tasks
&lt;&#x2F;span&gt;&lt;span&gt;│   └── main.yml
&lt;&#x2F;span&gt;&lt;span&gt;├── templates
&lt;&#x2F;span&gt;&lt;span&gt;└── vars
&lt;&#x2F;span&gt;&lt;span&gt;    └── main.yml
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now lets explain each of these.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;files&lt;&#x2F;strong&gt;: This directory contains files that will be copied to the host.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;handlers&lt;&#x2F;strong&gt;: These are basically tasks which are can be notified to be run after tasks are completed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;meta&lt;&#x2F;strong&gt;: This file cotains the meta information and dependency roles.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;templates&lt;&#x2F;strong&gt;: This directory contains templates that use variable subsitution and, then copy it in your host.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;tasks&lt;&#x2F;strong&gt;: It contains all of the tasks that the playbook needs to run.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;vars&lt;&#x2F;strong&gt;: These are variables that you can use in your roles.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prerequsites&quot;&gt;Prerequsites&lt;a class=&quot;zola-anchor&quot; href=&quot;#prerequsites&quot; aria-label=&quot;Anchor link for: prerequsites&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make sure you have access to a remote or local Ubuntu Server. I use &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;m.do.co&#x2F;c&#x2F;95bdc8dc8e65&quot;&gt;DigitalOcean&lt;&#x2F;a&gt; to cater for all my server needs since it is quick and easy to spin up machines.
&lt;strong&gt;Quick Bonus&lt;&#x2F;strong&gt;: if you sign up throught this &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;m.do.co&#x2F;c&#x2F;95bdc8dc8e65&quot;&gt;link&lt;&#x2F;a&gt; you get $10 in  &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;m.do.co&#x2F;c&#x2F;95bdc8dc8e65&quot;&gt;DigitalOcean&lt;&#x2F;a&gt; credit.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Also make sure you have a static website or a webpage as a git repository.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;blockquote&gt;
&lt;p&gt;All Ansible Playbooks are written in YAML.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Now lets get the ball rolling,&lt;&#x2F;p&gt;
&lt;p&gt;Clone the static website from the git respository. But, make sure you change the repo url. Additionally, make sure you set approriate variables in the vars folder. The &lt;code&gt;{{ user }}&lt;&#x2F;code&gt; variable has no default value so make sure you add one to the vars file.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;- name: Clone Blog From Github using HTTPS
&lt;&#x2F;span&gt;&lt;span&gt;  git:
&lt;&#x2F;span&gt;&lt;span&gt;    repo: https:&#x2F;&#x2F;github.com&#x2F;theshapguy&#x2F;bytes.git
&lt;&#x2F;span&gt;&lt;span&gt;    dest: &#x2F;home&#x2F;{{ user }}&#x2F;blog
&lt;&#x2F;span&gt;&lt;span&gt;    version: master
&lt;&#x2F;span&gt;&lt;span&gt;    update: yes
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We will use nginx as a webserver. You can also use &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;httpd.apache.org&#x2F;&quot;&gt;Apache&lt;&#x2F;a&gt; as well, however the following configuration is for nginx.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;- name: Install nginx
&lt;&#x2F;span&gt;&lt;span&gt;  apt:
&lt;&#x2F;span&gt;&lt;span&gt;    package: nginx
&lt;&#x2F;span&gt;&lt;span&gt;    state: latest
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, lets create a &lt;code&gt;template&lt;&#x2F;code&gt; configuration for nginx virtual host.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;server {
&lt;&#x2F;span&gt;&lt;span&gt;   listen 80;
&lt;&#x2F;span&gt;&lt;span&gt;   listen [::]:80;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;   server_name {{ domain }}  www.{{ domain }};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    root &#x2F;home&#x2F;{{ user }}&#x2F;blog;
&lt;&#x2F;span&gt;&lt;span&gt;    index index.html;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;   location &#x2F; {
&lt;&#x2F;span&gt;&lt;span&gt;       try_files $uri $uri&#x2F; =404;
&lt;&#x2F;span&gt;&lt;span&gt;   }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All &lt;code&gt;variables&lt;&#x2F;code&gt; are replaced using variables defined in the vars directory so make sure these are defined.&lt;&#x2F;p&gt;
&lt;p&gt;Copy this template and configure the nginx symlink. Also make sure that you have removed the default symlink which can cause confliting issues between two nginx configuration.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;- name: Copy Nginx Config for Blog to Host
&lt;&#x2F;span&gt;&lt;span&gt;  template:
&lt;&#x2F;span&gt;&lt;span&gt;    src: blog.conf.http.j2
&lt;&#x2F;span&gt;&lt;span&gt;    dest: &#x2F;etc&#x2F;nginx&#x2F;sites-available&#x2F;blog.nginx.conf
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;- name: Add Symlink to Host
&lt;&#x2F;span&gt;&lt;span&gt;  file:
&lt;&#x2F;span&gt;&lt;span&gt;    src: &#x2F;etc&#x2F;nginx&#x2F;sites-available&#x2F;blog.nginx.conf
&lt;&#x2F;span&gt;&lt;span&gt;    dest: &#x2F;etc&#x2F;nginx&#x2F;sites-enabled&#x2F;blog
&lt;&#x2F;span&gt;&lt;span&gt;    state: link
&lt;&#x2F;span&gt;&lt;span&gt;  notify: restart nginx
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;- name: Remove default symlink
&lt;&#x2F;span&gt;&lt;span&gt;  file:
&lt;&#x2F;span&gt;&lt;span&gt;    path: &#x2F;etc&#x2F;nginx&#x2F;sites-enabled&#x2F;default
&lt;&#x2F;span&gt;&lt;span&gt;    state: absent
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now lets create a handler to restart nginx. If there are any changes to the file the &lt;code&gt;notify&lt;&#x2F;code&gt; tag is executed and nginx is &lt;code&gt;reloaded&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;- name: reload nginx
&lt;&#x2F;span&gt;&lt;span&gt;  service: name=nginx state=reloaded
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  # basically you are doing -&amp;gt; sudo service nginx [options]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, your website should be running on your &lt;code&gt;{{ domain }}&lt;&#x2F;code&gt; as listed on your vars directory.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting Started with Android Animations</title>
        <published>2023-07-03T00:00:00+00:00</published>
        <updated>2023-07-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://shapath.com.np/posts/getting-started-with-android-animations/"/>
        <id>https://shapath.com.np/posts/getting-started-with-android-animations/</id>
        
        <content type="html" xml:base="https://shapath.com.np/posts/getting-started-with-android-animations/">&lt;p&gt;Android Animations has come a long way from Froyo to Honeycomb and then to Marshmallow. This has included a lot of API changes in Android. The truth - there is no animation library that you can just include in your app and they start automagically working. Animations need to be coded. There is no way around it. Even though, &lt;code&gt;animateLayoutChanges=&quot;true&quot;&lt;&#x2F;code&gt; has some nice usages, it’s likely rare.&lt;&#x2F;p&gt;
&lt;p&gt;When Material Design became the standard, Android went all out on colors and motion, moreover, delighting the user. Animations in Android have a complex vocabulary to learn, even though it has gotten easier over the years, it is still hefty. I might not even cover all the vocabulary in this post however it will give you a core idea of how to get started with animations on Android to delight your users. Android Docs are great! No doubt, however they are usually jargon to start out with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;view-animations&quot;&gt;View Animations&lt;a class=&quot;zola-anchor&quot; href=&quot;#view-animations&quot; aria-label=&quot;Anchor link for: view-animations&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;h4 id=&quot;animating-a-button&quot;&gt;Animating a button&lt;a class=&quot;zola-anchor&quot; href=&quot;#animating-a-button&quot; aria-label=&quot;Anchor link for: animating-a-button&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Views are animated with the ViewPropertyAnimator. With the fluent API you can just do view.animate() to start animating your views.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;animate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;translationY&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;alpha&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setDuration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setListener&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;AnimatorListenerAdapter&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;@Override
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;public void &lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;onAnimationCancel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;Animator &lt;&#x2F;span&gt;&lt;span&gt;animation) {
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;super&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;onAnimationCancel&lt;&#x2F;span&gt;&lt;span&gt;(animation)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;                btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setVisibility&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;View&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;GONE)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;            }
&lt;&#x2F;span&gt;&lt;span&gt;        })&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; They run in parallel, alpha and translationY
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Don’t override AnimatorListener, override AnimatorListenerAdapter. Try it!&lt;&#x2F;p&gt;
&lt;p&gt;I have seen developers at Google recommend this method as to the following one as it makes animations fluent.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;objectanimator&quot;&gt;ObjectAnimator&lt;a class=&quot;zola-anchor&quot; href=&quot;#objectanimator&quot; aria-label=&quot;Anchor link for: objectanimator&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;The other method is to use the ObjectAnimator.&lt;&#x2F;p&gt;
&lt;p&gt;ObjectAnimator fade = ObjectAnimator.ofFloat(btnAnimate, View.ALPHA, 0);
fade.start();
Interpolators&lt;&#x2F;p&gt;
&lt;h4 id=&quot;linear-vs-curve&quot;&gt;Linear vs Curve&lt;a class=&quot;zola-anchor&quot; href=&quot;#linear-vs-curve&quot; aria-label=&quot;Anchor link for: linear-vs-curve&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Animations need to look real to your user. A decelerating&#x2F;accelerating object always looks better than a object in linear motion.&lt;&#x2F;p&gt;
&lt;p&gt;Interpolator is another class in the API which makes it easy to define the rate of change of animations. These allow view properties like alpha and translate to be accelerated and decelerated (it does a lot more).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;animate&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setInterpolator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;AccelerateDecelerateInterpolator&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;setDuration&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;2500&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;alpha&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;translationY&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The interpolator changes the alpha of the view by accelerating the fade in the beginning and decelerating completely disappears from the screen. The same with translationY.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;sets-of-animations&quot;&gt;Sets of Animations&lt;a class=&quot;zola-anchor&quot; href=&quot;#sets-of-animations&quot; aria-label=&quot;Anchor link for: sets-of-animations&quot;&gt;#&lt;&#x2F;a&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Translate and Fade Off Screen&lt;&#x2F;p&gt;
&lt;p&gt;Your might be thinking, I can just do this, however animations run asynchronously hence the following code will run in parallel.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; First Translate
&lt;&#x2F;span&gt;&lt;span&gt;btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;animate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;translationY&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;400&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; Then Fade Out
&lt;&#x2F;span&gt;&lt;span&gt;btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;animate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;alpha&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; They both should run sequentially
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In comes the AnimationSet. This allows animations to be played sequentially, in parallel and a lot more. Basically, AnimationSet is the choreographer of your animations.&lt;&#x2F;p&gt;
&lt;p&gt;With AnimationSet you can no longer use the view.animate() but now are using the ObjectAnimator.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;java&quot; style=&quot;background-color:#2e3440;color:#d8dee9;&quot; class=&quot;language-java &quot;&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ObjectAnimator&lt;&#x2F;span&gt;&lt;span&gt; fade &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ObjectAnimator&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ofFloat&lt;&#x2F;span&gt;&lt;span&gt;(btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;View&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ALPHA&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ObjectAnimator&lt;&#x2F;span&gt;&lt;span&gt; translate &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;ObjectAnimator&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;ofFloat&lt;&#x2F;span&gt;&lt;span&gt;(btnAnimate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;View&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;TRANSLATION_Y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;400&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;AnimatorSet&lt;&#x2F;span&gt;&lt;span&gt; set &lt;&#x2F;span&gt;&lt;span style=&quot;color:#81a1c1;&quot;&gt;= new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fbcbb;&quot;&gt;AnimatorSet&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;set&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;playSequentially&lt;&#x2F;span&gt;&lt;span&gt;(translate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; fade)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;set&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#88c0d0;&quot;&gt;start&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eceff4;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; The button will translate and then fade out.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#616e88;&quot;&gt;&#x2F;&#x2F; This example is just scratching the surface.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the end…&lt;&#x2F;p&gt;
&lt;p&gt;With ViewPropertyAnimator, Interpolators and AnimatorSet you can choreograph many animations that delight the users with the use of motion. ViewPropertyAnimator has a lot of advantages of its predecessor ObjectAnimator, namely the fluent API. However ObjectAnimator still is the mother of all while choreographing complex animations. Also, don’t forget interpolators. Its these that make your animations delight the user.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2e3440;color:#d8dee9;&quot;&gt;&lt;code&gt;&lt;span&gt;NOTE: This is a article I had on my old blog that I ported over to this version.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
</feed>
