<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: sangarshanan</title>
    <description>The latest articles on DEV Community by sangarshanan (@sangarshanan).</description>
    <link>https://dev.to/sangarshanan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F186126%2F136ab6df-6bcb-46f5-a5e8-972e0fa9541d.png</url>
      <title>DEV Community: sangarshanan</title>
      <link>https://dev.to/sangarshanan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sangarshanan"/>
    <language>en</language>
    <item>
      <title>Curb your data with Huffman coding</title>
      <dc:creator>sangarshanan</dc:creator>
      <pubDate>Sun, 27 Dec 2020 20:44:56 +0000</pubDate>
      <link>https://dev.to/sangarshanan/curb-your-data-with-huffman-coding-5ecg</link>
      <guid>https://dev.to/sangarshanan/curb-your-data-with-huffman-coding-5ecg</guid>
      <description>&lt;p&gt;Transmitting messages meant converting the message into a sequence of symbols, The symbol or the sequence of symbols associated with a message is called the &lt;strong&gt;message code&lt;/strong&gt; while the entire number of messages being transmitted might be called a &lt;strong&gt;message ensemble&lt;/strong&gt;. The mutual agreement between the transmitter and the receiver about the meaning of the code for each message in the ensemble is called the &lt;strong&gt;ensemble code&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;The concept of minimum redundancy code will be defined as the code used by a message ensemble consisting of a finite number of members N and for the given number of coding digits D yields the lowest possible average message length&lt;/p&gt;

&lt;p&gt;This "Minimum Redundancy" or rather "Optimal" coding method had two rules&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No two messages will consist of an identical arrangement of coding digits &lt;/li&gt;
&lt;li&gt;No additional information would be needed to specify where the message code begins and ends once the starting point of a sequence of messages is known, this representation is called a &lt;strong&gt;prefix code&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second rule or the prefix code is important because we are dealing with a &lt;strong&gt;variable-length encoding&lt;/strong&gt; so there is a chance for ambiguity, i.e we might not know where the encoding of one symbol ends and the other begins, but designing out encoding as a prefix code means that the bit string representing some particular symbol is never a prefix of the bit string representing any other symbol which means no ambiguity whatsoever&lt;/p&gt;

&lt;p&gt;&lt;code&gt;01, 102, 111, 202&lt;/code&gt; is a valid prefix message code for an ensemble of four members, which means that&lt;br&gt;
&lt;code&gt;1111022020101111102&lt;/code&gt; can be broken up without any ambiguity into &lt;br&gt;
&lt;code&gt;111-102-202-01-01-111-102&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However, if the message code includes &lt;code&gt;11, 111, 102, and 02&lt;/code&gt; then a &lt;code&gt;11&lt;/code&gt; would result in ambiguity cause we will not know whether it corresponds to &lt;code&gt;11&lt;/code&gt; or to &lt;code&gt;111&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This rule forms the basis of &lt;strong&gt;Huffman Code&lt;/strong&gt; an optimal algorithm for lossless data compression.&lt;/p&gt;

&lt;p&gt;He proved his encoding as &lt;strong&gt;The most optimal way of assigning ones/zeros to a single character&lt;/strong&gt; in his paper title &lt;strong&gt;A Method for the Construction of Minimum-Redundancy Codes&lt;/strong&gt; which is the shortest paper I have ever read ! so quick shoutout to my man David for that.&lt;/p&gt;

&lt;p&gt;Huffman coding turned the existing Shannon coding upside down and used a &lt;strong&gt;Bottoms up Approach&lt;/strong&gt; i.e &lt;strong&gt;Merging from the leaves to the root&lt;/strong&gt; to generate the tree.&lt;/p&gt;

&lt;p&gt;Let's suppose we need to encode &lt;code&gt;A B C D&lt;/code&gt; and all of them equal probabilities of occurrence &lt;code&gt;1/4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0s6S4QAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/Sangarshanan/sangarshanan.github.io/master/img/in-post/huffman-tree.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0s6S4QAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/Sangarshanan/sangarshanan.github.io/master/img/in-post/huffman-tree.png" alt="huffman-tree.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We generate a tree out of the probabilities such that the second level nodes sum up to &lt;code&gt;1/2&lt;/code&gt; and the root node sums up to &lt;code&gt;1&lt;/code&gt;. We then use this tree to paint all the left nodes 1 and right nodes 0. Then the encodings are generate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A - 11
B - 10
C - 01 
D - 00

Length = 2,2,2,2
Since the probabilities are the same the length of the code is always 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well now if we chose to point the left nodes as 0 and right nodes as 1&lt;br&gt;
the coding we would be the reverse but will still end up being a prefix code and optimal.&lt;/p&gt;

&lt;p&gt;Entropy of the code &lt;code&gt;H = Σ Pi log(1/Pi)&lt;/code&gt; =  0.5+0.5+0.5+0.5 = 2 &lt;/p&gt;

&lt;p&gt;Expected code length = &lt;code&gt;L = Σ pi Li&lt;/code&gt; = 4(1/4*2) = 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                      Entropy (H)
Efficiency (E) =  ━━━━━━━━━━━━━━━━━━━━
                Expected Word length (L) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E = 2/2 = 1 ~ 100 percent :)&lt;/p&gt;

&lt;p&gt;But this was easy cause the probabilities were all powers of 2 which might not always be the case&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7IrjKawc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/Sangarshanan/sangarshanan.github.io/master/img/in-post/huffman-tree-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7IrjKawc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/Sangarshanan/sangarshanan.github.io/master/img/in-post/huffman-tree-2.png" alt="huffman-tree.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A - 0
B - 10
C - 110 
D - 1110 
E - 1111

Length = 1, 2, 3, 4, 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this above diagram, the probabilities are not powers of 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Entropy of the code H = Σ Pi log(1/Pi) 
= 2(1/3*log_2 (3)) + 3(1/9 * log_2 (9))
= 2.113

Expected code length = L = Σ pi Li
= (1/3 * 1) + (1/3 * 2) +(1/9 * 3) +(1/9 * 4) +(1/9 * 4) 
= 2.222
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Efficiency (E)&lt;/code&gt; = 2.113/ 2.222 = 0.95 ~ 95 Percent Efficiency&lt;/p&gt;

&lt;p&gt;Here is the algorithm, For a given string of characters &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculate the frequency of each character in the string.&lt;/li&gt;
&lt;li&gt;Sort the characters in increasing order of the frequency&lt;/li&gt;
&lt;li&gt;Make each unique character as a leaf node.&lt;/li&gt;
&lt;li&gt;Create an empty node. Assign the minimum frequency as the left child and the second minimum frequency as the right child of the node.&lt;/li&gt;
&lt;li&gt;Assign the empty node a value that is the sum of the above two minimum frequencies.&lt;/li&gt;
&lt;li&gt;Repeat till we reach the maximum frequency character that would have a node one step away from the root node, which means the least number of bits to represent it. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic idea is to create a binary tree and operate on it in a bottoms-up manner so that the least two frequent characters are as far as possible from the root. In this way, the most frequent character gets the smallest code and the least frequent character gets the largest code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;Huffman Coding can be implemented with a priority queue, Here is a rough pseudoscope&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Count the occurrences of each character in the string&lt;/li&gt;
&lt;li&gt;Place characters and counts into a priority queue&lt;/li&gt;
&lt;li&gt;Use priority queue to create Huffman tree&lt;/li&gt;
&lt;li&gt;Traverse the tree and assign right nodes 1 and left nodes 0&lt;/li&gt;
&lt;li&gt;Encode the string with the binary mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code is in the repo and has a Notebook that visualizes the generated huffman tree&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sangarshanan/huffman-coding/blob/master/notebook.ipynb"&gt;https://github.com/sangarshanan/huffman-coding/blob/master/notebook.ipynb&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reference&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://compression.ru/download/articles/huff/huffman_1952_minimum-redundancy-codes.pdf"&gt;http://compression.ru/download/articles/huff/huffman_1952_minimum-redundancy-codes.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.toronto.edu/%7Eradford/csc310.F11/week3.pdf"&gt;https://www.cs.toronto.edu/~radford/csc310.F11/week3.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=JsTptu56GM8"&gt;https://www.youtube.com/watch?v=JsTptu56GM8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>python</category>
      <category>beginners</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Morse Code &amp; The Beginning of an era</title>
      <dc:creator>sangarshanan</dc:creator>
      <pubDate>Sun, 27 Dec 2020 20:38:34 +0000</pubDate>
      <link>https://dev.to/sangarshanan/morse-code-the-beginning-of-an-era-4koc</link>
      <guid>https://dev.to/sangarshanan/morse-code-the-beginning-of-an-era-4koc</guid>
      <description>&lt;p&gt;Original post: &lt;a href="https://sangarshanan.github.io/2020/12/20/morse-codes/"&gt;https://sangarshanan.github.io/2020/12/20/morse-codes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Humans are social animals, we rely on friends and family maybe now it's just for social juice but when we were still living in jungles staying together meant better higher chances of survival. We have evolved by cooperating as a civilization and we were able to continue that cooperation for generations with effective communication.&lt;/p&gt;

&lt;p&gt;Humans are also expansionists we like to explore into the unknown whether it is across towns, cities, countries, planets, solar systems, galaxies, or even superclusters and as we humans explored places on earth and set up colonies it got a bit harder to communicate across colonies that were a bit far apart, we started by using natural resources for long term communication, smoke signals and drumbeats were common means of communications in almost all ancient civilizations. But this was limited by the weather and line of sight. We mitigated the line of sight issue by setting up communication channels on hilltops by this too was limited by the weather.&lt;/p&gt;

&lt;p&gt;We then started developing infrastructure for long term communication, animals like pigeons, and even human messengers were trained to deliver messages across long distances. This was obviously was slow but kinda worked out for a while&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Enter Electricity&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Around 600 BC the Greek mathematician Thales of Miletus observed something interesting, certain stones like amber when rubbed against fur would showcase a strange force that could attract small fibers. Not only this it was also observed that when you try to touch this invisible force it would give you a shock and then immediately disappear. Also, not every object would allow the flow of this force, today we know these objects as conductors.&lt;/p&gt;

&lt;p&gt;In 1752 Benjamin Franklin would discover that the tiny shocks we get from the force of friction between certain objects as discussed above were also the same force observed in lightning as it gave him the same shock, Not only this he was also able to store this so-called energy in a glass jar filled with water a protruding wire and discharge it all will by connecting wires or touching the jar. This was the very first Capacitor. &lt;/p&gt;

&lt;p&gt;Once we discovered about free-flowing of electrons across opposing charges, its resulting magnetic field, and an effective way to store and transmit this electrical power over a conductor there was no turning back. Electricity kinda like fire was a quicksave in the species game.&lt;/p&gt;

&lt;p&gt;The Electric Telegraph was a result of two developments in the field of electricity. First, in 1800, the Italian physicist Alessandro Volta invented the battery, which reliably stored electric current and allowed it to be used in a controlled environment. Second, in 1820, the Danish physicist Hans Christian Oersted demonstrated the connection between electricity and magnetism by deflecting a magnetic needle with an electric current.&lt;/p&gt;

&lt;p&gt;In the 1830s, the British team of Cooke and Wheatstone developed a telegraph system, It was suddenly possible to communicate with electricity over long distances by just laying some wires. &lt;/p&gt;

&lt;p&gt;But there was an issue they could only communicate through pulses of electricity. This where Samuel Morse came in he developed a sorta code, more particularly morse code to translate these pulses to numbers. He later sought help from Alfred Vail and Leonard Gale to expand its scope to letters and other characters.&lt;/p&gt;

&lt;p&gt;The code assigned a sequence and short and long pulses to numbers and letters. These pulses can also be described as dots and dashes, For example, the code for A is &lt;code&gt;🔴 🚥&lt;/code&gt; a dot followed by a dash. Each dot represents one time unit and a dash represents three time units, there is also a silence of 1 time unit in between every pulse.&lt;/p&gt;

&lt;p&gt;Here is the interesting problem statement &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which specific sequence to dots and dashes do you assign to a character ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To do this they actually studied the frequency of usage of every character in the English language and assigned easier sequences to the more commonly used characters. So &lt;code&gt;E&lt;/code&gt; the most commonly used letter is represented with a single 🔴 dot.&lt;/p&gt;

&lt;p&gt;Morse codes were a gamechanger and was a huge step towards enabling humans to communicate over really long distances like never before. Even now in maritime and a bunch of other places we use &lt;code&gt;SOS&lt;/code&gt; as a signal for distress calls and the combination of these letters were chosen purely for their simplicity in morse code.&lt;/p&gt;

&lt;p&gt;On an entirely different note, Samuel Morse was a painter by profession. The city of New York promised him a $1,000 commission to paint Marquis de Lafayette and while working on the painting he got a letter from a man on horseback and the letter said that his wife Lucretia had passed away and by the time he rushed back to see her one last time she was already buried, perhaps it was this heartbeat and pain caused by slow communication that gave us morse code.  &lt;/p&gt;

&lt;p&gt;Despite being a little hard and not intuitive to learn once mastered morse code is actually one of the easiest means of communication, It has been used by spies to deliver secret messages which to an unsuspecting onlooker might seem like weird blinking or tapping. There have also been multiple references to it in pop culture, more recently I saw one in the movie parasite where (spoiler alert) the man who lives inside the mansion communicates with its owner by banging his dead and switching the lights on and off in morse code.&lt;/p&gt;

&lt;p&gt;Now, this seems all too familiar to like minds, morse code using two types of pulses short and long to encode information which is kinda what every computer ever does right ? so is this all just an elaborate ploy by the omnipresent 1 and 0s&lt;/p&gt;

&lt;p&gt;So its all binary then ?&lt;/p&gt;

&lt;p&gt;Ehhhhh not exactly, so the think is with morse code we have a gap of one time unit between dots and dashes, to separate letters we use the three time units and to separate words we use seven time units &lt;/p&gt;

&lt;p&gt;So morse code is no exactly a binary system but a ternary system cause we also need to account for silence or gaps i.e time units when there are no pulses. &lt;/p&gt;

&lt;p&gt;That's is not stopping us from representing this in binary&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dot is denoted by a &lt;code&gt;10&lt;/code&gt; 1 representing the time unit and 0 representing the end of the pulse&lt;/li&gt;
&lt;li&gt;A dash is denoted by &lt;code&gt;110&lt;/code&gt; where 111 represents 3 time units and it too ends with a 0 to denote the one time unit gap or the end of a pulse&lt;/li&gt;
&lt;li&gt;A gap is denoted by &lt;code&gt;00&lt;/code&gt; which is two time units of nothingness so when combined with either a dot or a dash mean a letter separator and 3 continuos gaps represent the end of the word&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And there you have it !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|--------+------+--------+-----------|
| Letter | Code | Length | Frequency |
|--------+------+--------+-----------|
| E      | 🔴    |      1 |    12.49% |
| T      | 🚥    |      3 |     9.28% |
| A      | 🔴🚥   |      4 |     8.04% |
| O      | 🚥🚥🚥  |      9 |     7.64% |
| I      | 🔴   |      2 |     7.57% |
| N      | 🚥🔴   |      4 |     7.23% |
| S      | 🔴  |      3 |     6.51% |
| R      | 🔴🚥🔴  |      5 |     6.28% |
| H      | 🔴 |      4 |     5.05% |
| L      | 🔴🚥🔴 |      6 |     4.7% |
| D      | 🚥🔴  |      5 |     3.82% |
| C      | 🚥🔴🚥🔴 |      8 |     3.34% |
| U      | 🔴🚥  |      5 |     2.73% |
| M      | 🚥🚥   |      6 |     2.51% |
| F      | 🔴🚥🔴 |      6 |     2.40% |
| P      | 🔴🚥🚥🔴 |      8 |     2.14% |
| G      | 🚥🚥🔴  |      7 |     1.87% |
| W      | 🔴🚥🚥  |      7 |     1.68% |
| Y      | 🚥🔴🚥🚥 |     10 |     1.66% |
| B      | 🚥🔴 |      6 |     1.48% |
| V      | 🔴🚥 |      6 |     1.05% |
| K      | 🚥🔴🚥  |      7 |     0.54% |
| X      | 🚥🔴🚥 |      8 |     0.23% |
| J      | 🔴🚥🚥🚥 |     10 |     0.16% |
| Q      | 🚥🚥🔴🚥 |     10 |     0.12% |
| Z      | 🚥🚥🔴 |      8 |     0.09% |
|--------+------+--------+-----------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The representations in morse code was designed so that the most frequently used letters have the shortest codes. In general, code length increases as frequency decreases.&lt;/p&gt;

&lt;p&gt;This is actually a form of data compression and perhaps one of the earliest if not the first one.&lt;/p&gt;

&lt;p&gt;More work on compression was brought by pioneers of information theory, In 1949 Claude Shannon and Robert Fano devised a systematic way to assign codewords based on probabilities of blocks&lt;/p&gt;

&lt;p&gt;Even the morse code can be represented in graphical form, We have dots, dashes, word space and letter spaces and There are two states depending on whether or not a space was the last symbol transmitted. If so, then only a dot or a dash can be sent next and the state always changes. If not, any symbol can be transmitted and the state changes if a space is sent or remains the same. &lt;/p&gt;

&lt;p&gt;This concept of &lt;strong&gt;Modelling Sequences of random events using states and transitions between them is called a Markov Chain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This markov chain in the image above was presented in Claude Shannon's paper titled The Mathematical Theory of Communication, the paper which laid the foundations of modern information theory.&lt;/p&gt;

&lt;p&gt;It was also in this paper that Shannon introduced the Shannon-Fano coding, a technique for lossless data compression, this was preceded by a more optimal algorithm proposed by David Huffman in 1951, it was called Huffman encoding.&lt;/p&gt;

&lt;p&gt;Ah yes back when naming things after yourself was cOoL&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reference material&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.history.com/topics/inventions/telegraph"&gt;https://www.history.com/topics/inventions/telegraph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=HY_OIwideLg"&gt;https://www.youtube.com/watch?v=HY_OIwideLg&lt;/a&gt; of course it's a Vsauce video&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.khanacademy.org/computing/computer-science/informationtheory/"&gt;https://www.khanacademy.org/computing/computer-science/informationtheory/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>'Tis Build-a-Loadbalancer Day</title>
      <dc:creator>sangarshanan</dc:creator>
      <pubDate>Sat, 17 Oct 2020 09:29:24 +0000</pubDate>
      <link>https://dev.to/sangarshanan/tis-build-a-loadbalancer-day-5bd7</link>
      <guid>https://dev.to/sangarshanan/tis-build-a-loadbalancer-day-5bd7</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Loadbalancing a way of effectively distributing incoming network traffic across a group of backend servers, so normally in services you have clients and you have server that process the request of your client and when we wanna scale we just add more servers for the clients to get served from, load balancer sits in the middle of this process by accepting requests from clients and routing it to the server, it also does this in a way that optimizes for speed, effective utilization and makes sure that things work even when one of the servers go down.&lt;/p&gt;

&lt;p&gt;A very cool analogy I read for this is that of a support center, we are clients whereas the support staff are servers and when we call them the phone line is essentially a loadbalancer cause it has to route our call to one of the available support staff.  &lt;/p&gt;

&lt;p&gt;So now that we know the loadbalancer distributes the load, lets talk about how it does it&lt;/p&gt;

&lt;h4&gt;
  
  
  Round Robin
&lt;/h4&gt;

&lt;p&gt;Here, we distribute the load sequentially among servers.&lt;br&gt;
In this strategy we can either assume that all backends have the same processing power or use weights set relative to the processing power&lt;/p&gt;
&lt;h4&gt;
  
  
  Least connections
&lt;/h4&gt;

&lt;p&gt;We prefer the server with the fewest connections to the client. The relative computing capacity of each server is also factored into determining which one has the least connections&lt;/p&gt;
&lt;h4&gt;
  
  
  Least time
&lt;/h4&gt;

&lt;p&gt;Sends requests to the server selected by a formula that combines the&lt;br&gt;
fastest response time and fewest active connections.&lt;/p&gt;

&lt;p&gt;We can also define custom strategies, it all depends on what we wanna do which for me is mostly falling back to defaults. &lt;/p&gt;
&lt;h3&gt;
  
  
  Execution
&lt;/h3&gt;

&lt;p&gt;So our end result should look something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/r/strm/helloworld-http/"&gt;https://hub.docker.com/r/strm/helloworld-http/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a docker-compose file with hello world servers and an nginx loadbalancer to distribute the requests, so we just need to replace that with the one we a new one.&lt;/p&gt;

&lt;p&gt;Lets define the steps before actually building it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our service is running Huzzah !!&lt;/li&gt;
&lt;li&gt;Hoomans start calling our service, sometimes many and sometimes simultaneously&lt;/li&gt;
&lt;li&gt;For every human that request to use our service we first receive the request start to determine the server that needs to serve the request, we do some &lt;code&gt;magic()&lt;/code&gt; to get the server that needs to serve the traffic (We discussed some of those magics in the introduction)&lt;/li&gt;
&lt;li&gt;We then serve the traffic through that server, Hooman is happy now !!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lets actually name our loadbalancer, I hereby declare thee &lt;code&gt;anubis&lt;/code&gt;, cause the god nicely balances souls and their worth&lt;/p&gt;

&lt;p&gt;Now that the naming ceremony is over, To be able to do this "magic" we discussed earlier we need metadata on all the servers that are actually serving requests like if its alive, the computing capacity, number of connections to the client and maybe even more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Servers have the same computing capacity
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="c1"&gt;# localhost:8080
&lt;/span&gt;    &lt;span class="n"&gt;alive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="c1"&gt;# Dead or Alive
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end we will have a list of servers that can serve the client.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[Server1, Server2, Server3]&lt;/code&gt; &amp;lt;========&amp;gt;✨ Magic✨ &amp;lt;========&amp;gt; &lt;code&gt;Route to Server1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's write this magic, well gonna call it &lt;code&gt;Strategy&lt;/code&gt; for sanity&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Server1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Server2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Server3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;alive_servers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_alive_servers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;round_robin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;robin_goes_round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alive_servers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the last step is to route use the client to the server returned by the output, to do this we are gonna use a simple reverse proxy, its kinda similar to a loadbalancer in the sense that it basically accepts a request from a client, forwards it to a server that can fulfill it, and returns the server’s response to the client. it often makes sense to deploy a reverse proxy when you have just one server cause then you have don't have the need for distributing requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/"&gt;https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can write a simple reverse proxy with &lt;code&gt;requests&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="s"&gt;"""Reverse Proxy."""&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;http.server&lt;/span&gt;  
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;socketserver&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"www.google.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allow_redirects&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Content-Length'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Fetches content from localhost:8000
&lt;/span&gt;&lt;span class="n"&gt;httpd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socketserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TCPServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;httpd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;serve_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this and when you goto localhost:8080 you get redirected to google, Finally !! google running on my localhost. Screw the Internet. But this is a very stupid reverse proxy that only works on GET request and in pages with no dynamic elements&lt;/p&gt;

&lt;p&gt;But then I had a question, why don't we just do a redirect how is it different from a reverse proxy. I looked online and found an explanation on stackoverflow (obviously). So with a redirect the server tells the client to look elsewhere for the resource. The client will be aware of this new location. The new location must be reachable from the client. A reverse proxy instead forwards the request of the client to some other location itself and sends the response from this location back to the client. This means that the client is not aware of the new location and that the new location does not need to be directly reachable by the client&lt;/p&gt;

&lt;p&gt;Code is up on &lt;a href="https://github.com/Sangarshanan/anubis"&gt;https://github.com/Sangarshanan/anubis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I noticed immediately was that Python's http.serve is hella slow and when I tried opening multiple tabs it straight up died on me, which is kinda bad this is when I found out about &lt;code&gt;ThreadedHTTPServer&lt;/code&gt; and &lt;code&gt;ForkingMixIn&lt;/code&gt;. So we can either spawn multiple threads or processes to handle requests &lt;a href="https://pymotw.com/2/BaseHTTPServer/index.html#module-BaseHTTPServer"&gt;https://pymotw.com/2/BaseHTTPServer/index.html#module-BaseHTTPServer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well its kinda better now but not awesome, we need something like &lt;a href="https://github.com/http-party/http-server"&gt;https://github.com/http-party/http-server&lt;/a&gt; to take full advantage of asynchronous IO for concurrent handling of requests. We can only scale so much serialising requests and with python we will always be blocked by GIL so not the perfect candidate to do this but a fun exercise nonetheless. &lt;/p&gt;

&lt;h3&gt;
  
  
  Swiper
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.nginx.com/resources/glossary/load-balancing/"&gt;https://www.nginx.com/resources/glossary/load-balancing/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kasvith.me/posts/lets-create-a-simple-lb-go/"&gt;https://kasvith.me/posts/lets-create-a-simple-lb-go/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Realtime channels with FastAPI + Broadcaster</title>
      <dc:creator>sangarshanan</dc:creator>
      <pubDate>Tue, 30 Jun 2020 19:06:13 +0000</pubDate>
      <link>https://dev.to/sangarshanan/realtime-channels-with-fastapi-broadcaster-47jh</link>
      <guid>https://dev.to/sangarshanan/realtime-channels-with-fastapi-broadcaster-47jh</guid>
      <description>&lt;p&gt;Websockets are awesome, just learnt that before websockets people were polling (eww). Well actually polling helps when you know the exact time interval of your refresh But we are gonna be the cool realtime streamers. &lt;/p&gt;

&lt;p&gt;Websockets allow full-duplex, bidirectional connections between a client and a server over the web with a single TCP connection (A protocol for sending and receiving packets of data across IPs in a reliable way, simply by acknowledgement)&lt;/p&gt;

&lt;p&gt;We are gonna be using &lt;a href="https://github.com/tiangolo/fastapi" rel="noopener noreferrer"&gt;Fastapi&lt;/a&gt; and &lt;a href="https://github.com/encode/starlette" rel="noopener noreferrer"&gt;Starlette&lt;/a&gt; to define Websocket endpoint and &lt;a href="https://github.com/encode/broadcaster" rel="noopener noreferrer"&gt;Broadcaster&lt;/a&gt; to publish messages to this websocket. Others can just subscribe to the websocket endpoint to receive the published messages in real time &lt;/p&gt;

&lt;p&gt;So this is what my API looks like, there is just one endpoint to publish messages to a channel (lebowski). Now the goal is to have a websocket that hoomans/robots can subscribe to follow the updates to lebowski in real time.&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lebowski&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

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

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/push&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;push_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We are gonna use broadcaster and Starlette to define a websocket endpoint&lt;/p&gt;

&lt;p&gt;With starlette we can use WebSocketEndpoint and use it to create a WebsocketRoute, WebSocketEndpoint has three overridable methods for handling specific ASGI websocket message types: on_connect, on_receive, on_disconnect. &lt;/p&gt;

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

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Echo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WebSocketEndpoint&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Message text was: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_disconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;close_code&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;WebSocketRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/ws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Echo&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This is a simple echo websocket that send back what it receives. But I am not worrying about all this I am using broadcaster. With broadcaster we can define a simple broadcasting API onto a number of different backend services like Redis PUB/SUB, Kafka, Postgres LISTEN/NOTIFY or an in-memory one.&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;starlette.concurrency&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;run_until_first_complete&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;starlette.routing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WebSocketRoute&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;broadcaster&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Broadcast&lt;/span&gt;

&lt;span class="n"&gt;broadcast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Broadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgresql://postgres@localhost/test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;events_ws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;run_until_first_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events_ws_receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;websocket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events_ws_sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;websocket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;events_ws_receiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_text&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;events_ws_sender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;WebSocketRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/events&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events_ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;events_ws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We have defined two async functions to receive and publish messages and passed it to a starlette WebSocketRoute. Used Postgres as a backend for the broadcaster.&lt;/p&gt;

&lt;p&gt;Now that we have defined a websocket route with broadcaster, lets just add it FastAPI and seal the deal&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;on_startup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;on_shutdown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/push&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;push_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;I have added the websocket route to the FastAPI app and am publishing to the channel on every call to the API.&lt;/p&gt;

&lt;p&gt;Now to test things I am writing a dummy subscriber to listen to the broadcast (With the API is running on port 1234)&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;websockets.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ConnectionClosed&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connected..&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;websocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ws://localhost:1234/events&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ConnectionClosed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not able to connect.. Retying in 3 seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_event_loop&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;run_until_complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's it :) In action below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsangarshanan.github.io%2Fimg%2Fcmd_websocket.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsangarshanan.github.io%2Fimg%2Fcmd_websocket.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok lastly, FastAPI is awesome and I have been using a lot lately. It's powerful, easy to learn and the async community powering the whole ecosystem makes me wanna cry happy tears 😭&lt;/p&gt;

&lt;p&gt;:wq&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Behind your Web Application (WSGI + Web server)</title>
      <dc:creator>sangarshanan</dc:creator>
      <pubDate>Sat, 16 Nov 2019 09:41:39 +0000</pubDate>
      <link>https://dev.to/sangarshanan/behind-your-web-application-wsgi-web-server-2hai</link>
      <guid>https://dev.to/sangarshanan/behind-your-web-application-wsgi-web-server-2hai</guid>
      <description>&lt;p&gt;When I started writing simple flask web applications back in college I did not actually undertand what was happening in the back when I run the flask application&lt;/p&gt;

&lt;p&gt;So when I run &lt;code&gt;python app.py&lt;/code&gt; , this pops up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; * Serving Flask app "somename"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I am able to interact with the applications by sending requests and getting a responses but how am I able to that... I did not do anything to make that happen.. I just wrote the logic and Flask did it for me and I was able to get stuff done really fast &lt;/p&gt;

&lt;p&gt;It's almost similar even when you look at other frameworks like Django&lt;/p&gt;

&lt;p&gt;Django provides tons of stuff out of the box for you like routing, views, templates, authentication, middleware and a whole lot more with a very rich documentation so that you are always in your comfort zone. And with a huge community any issue I faced with Django was one stackoverflow answer away&lt;/p&gt;

&lt;p&gt;These frameworks wrap everthing up so you just write in your logic and you are able to send requests and handle responses &lt;/p&gt;

&lt;p&gt;By running your application and sending HTTP requests, you realise 3 things happening in the HTTP flow  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You open a TCP connection: (In my case it's the localhost) The TCP connection is used to send a request, or several, and receive an answer. The client may open a new connection, reuse an existing connection, or open several TCP connections to the servers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send an HTTP request message with your application&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr


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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;You get a response from the server which you process with your application
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html

&amp;lt;!DOCTYPE html... (here comes the 29769 bytes of the requested web page)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you close or reuse the connection &lt;/p&gt;

&lt;p&gt;But then how the hell do these python framework handle HTTP requests ? Cause it seems like magic... and I would love to learn a trick or two so let's break it down :D&lt;/p&gt;

&lt;p&gt;Well maybe your site is static and you have all your files saved  &lt;/p&gt;

&lt;p&gt;Then for every request you already have corresponding static file as a reponse... awesome this is really fast, you could do tons of caching techniques and it's all really easy and straightforward but I mean it's static which means that you have to manually go and edit the html files every time &lt;/p&gt;

&lt;p&gt;To solve this issue arose the Common gateway interface which invokes a script that dynamically generates the web page&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Common Gateway Interface (CGI) offers a standard protocol for web servers to execute programs that execute like console applications (also called command-line interface programs) running on a server that generates web pages dynamically&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;The HTTP request that comes in breaks down into ENV variables which act as input and invokes a script which acts as a function and you get your output as an STDOUT... So if you just print hello world, it would be yout http response &lt;/p&gt;

&lt;p&gt;As cool and simple as all this sounds, you can't afford to run the script every time you get a request &lt;/p&gt;

&lt;p&gt;So we need a seperate out the web server and the python application &lt;/p&gt;

&lt;p&gt;Enter WSGI &lt;/p&gt;

&lt;p&gt;Or as the cool people call it Web server gateway interface &lt;/p&gt;

&lt;p&gt;WSGI can be implemented with a simple function and every time there is a request we just call the function instaead of running an entire script &lt;/p&gt;




&lt;p&gt;&lt;em&gt;It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;WSGI is not a server, a python module, a framework, an API or any kind of software. It is just an interface specification by which server and application communicate&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Well this means freedom cause we don't really need to worry about web servers like nginx or apache given that they understood this common interface and we could easily switch anytime we wanted to&lt;/p&gt;

&lt;p&gt;Also there is a really cool article comparing these two web servers &lt;a href="https://serverguy.com/comparison/apache-vs-nginx/" rel="noopener noreferrer"&gt;https://serverguy.com/comparison/apache-vs-nginx/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you wanted to build your own framework then you don't have to know a whole lot of HTTP and instead build something that implements this simple function (The one below is Gunicorn)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def app(environ, start_response):
    data = b"Hello, World!\n"
    start_response("200 OK", [
        ("Content-Type", "text/plain"),
        ("Content-Length", str(len(data)))
    ])
    return iter([data])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function take two arguments &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;start_response: This is invoked with a status code, headers and an iterable data that you wanna send back (here it's the generic hello world) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;environ: Well this is dictionary with some information like REQUEST_METHOD, PATH_INFO, SERVER_PROTOCOL etc&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WSGI servers like Gunicorn are designed to handle many requests concurrently. Frameworks are not made to process thousands of requests and determine how to best route them from the server. They can also communicate with multiple web servers and keep multiple processes of the web application running. They can also async (Bjoern which is actually faster but not compatible with HTTP/1.1)&lt;/p&gt;




&lt;p&gt;Gunicorn describes itself as a Pre-fork web server which means that a master creates forks which handle each request. A fork is a completely separate process and the "pre" part actually means that worker processes are created in advance, so that time is not wasted forking only when a worker is needed&lt;/p&gt;




&lt;p&gt;A very commonly used combo includes Nginx + Gunicorn + Django where Gunicorn acts as a middleware between nginx and the Django&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frukbottoland.com%2Fmedia%2Fimages%2Farquitectura-django-gunicorn-nginx-supervisor.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frukbottoland.com%2Fmedia%2Fimages%2Farquitectura-django-gunicorn-nginx-supervisor.jpg" alt="img"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now with Gunicorn why the hell do we need Nginx... seems unnecessary to me &lt;/p&gt;

&lt;p&gt;Well with Gunicorn Ngnix acts as a reverse proxy server which can be used to provide load balancing, provide web acceleration through caching or compressing inbound and outbound data, and provide an extra layer of security by intercepting requests headed for back-end servers and also gunicorn is designed to be an application server that sits behind a reverse proxy server that handles load balancing, caching, and preventing direct access to internal resources.&lt;/p&gt;

&lt;p&gt;Actually python comes with it's own built-in web server that provides standard GET and HEAD request handlers. You can use this to turn any directory in your system into your web server directory. I have actually used this to share code and stuff with my peers and it's pretty handy &amp;lt;3&lt;/p&gt;

&lt;p&gt;Now to reaffirm the fact that i have learnt somethings let's write sum fresh code with Sockets... ughh...Now I'm glad I don't have to do this everytime I write a webapp&lt;/p&gt;

&lt;p&gt;Now let's run this code to start a simple web server on port 8000&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import socket
HOST = '' ## Symbolic name meaning all available interfaces
PORT = 8000 ## Port 8000

'''
AF_INET is an address family that is used to designate the 
type of addresses that your socket can communicate with (in this case, Internet Protocol v4 addresses). 

SOCK_STREAM is a constant indicating the type of socket (TCP),
'''
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

'''
Set the value of the given socket option
When retrieving a socket option, or setting it, 
you specify the option name as well as the level. When level = SOL_SOCKET, 
the item will be searched for in the socket itself.

For example, suppose we want to set the socket option 
to reuse the address to 1 (on/true),
we pass in the "level" SOL_SOCKET and the value we want it set to.

This will set the SO_REUSEADDR in my socket to 1.
'''

listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

## Bind to the host and port
listen_socket.bind((HOST, PORT))

## Listen to the host/port
listen_socket.listen(1)
print(f'Serving your very own HTTP on port {PORT} ...')

while True:
    client_connection, client_address = listen_socket.accept()
    """
    The recv() function receives data on a socket 
    with descriptor socket and stores it in a buffer. 
    """
    request_data = client_connection.recv(1024)
    print(request_data.decode('utf-8')) ## Decode the data assuming UTF=8 Endoding

    http_response = b"""\
HTTP/1.1 200 OK

Sample Response to be parsed!
"""
    ## Send a response and close the connection
    client_connection.sendall(http_response)
    client_connection.close()

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

&lt;/div&gt;



&lt;p&gt;Run the file.. I've saved it as webserver.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python webserver.py                                                                                                                 
Serving your very own HTTP on port 8888 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;curl -v http://localhost:8000/&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
&amp;gt; GET / HTTP/1.1
&amp;gt; Host: localhost:8000
&amp;gt; User-Agent: curl/7.58.0
&amp;gt; Accept: */*
&amp;gt; 
&amp;lt; HTTP/1.1 200 OK
* no chunk, no close, no size. Assume close to signal end
&amp;lt; 
Sample Response to be parsed!
* Closing connection 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe also try&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;telnet localhost 8000&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

HTTP/1.1 200 OK

Sample Response to be parsed!
Connection closed by foreign host.

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

&lt;/div&gt;



&lt;p&gt;There you go a simple web server to send requests and get responses&lt;/p&gt;

&lt;p&gt;Now you can write your own web framework to interact with this web server and you would have essentially written your own application from scratch &lt;/p&gt;

&lt;p&gt;Essentially you get parsed responses for processing / storing or whatever it is you are into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests
r = requests.get('http://127.0.0.1:8000/') 
print(r.content) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different web frameworks communicate with web servers in different ways  &lt;/p&gt;

&lt;p&gt;In pyramid you have an application object that comes back from make&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from pyramid.config import Configurator
from pyramid.response import Response


def hello_world(request):
    return Response(
        'Hello world from Pyramid!\n',
        content_type='text/plain',
    )

config = Configurator()
config.add_route('hello', '/hello')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()

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

&lt;/div&gt;



&lt;p&gt;Flask is actually build around Werkzeug which is a WSGI web application library and Flask wraps Werkzeug, using it to handle the details of WSGI while providing more structure and patterns for defining powerful applications. In flask we actually define this as the app that we use as a decorator for our views and it's got routing and other functionalities built into it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask
from flask import Response
flask_app = Flask('flaskapp')


@flask_app.route('/hello')
def hello_world():
    return Response(
        'Hello world from Flask!\n',
        mimetype='text/plain'
    )

app = flask_app.wsgi_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contains stolen content from&lt;br&gt;&lt;br&gt;
 &lt;a href="https://github.com/rspivak/lsbaws" rel="noopener noreferrer"&gt;https://github.com/rspivak/lsbaws&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://www.youtube.com/watch?v=WqrCnVAkLIo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=WqrCnVAkLIo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You scrolled to the end :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>django</category>
    </item>
  </channel>
</rss>
