<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>General on Arunrocks</title>
    <link>https://arunrocks.com/tags/general/</link>
    <description>Recent articles in General on Arunrocks</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 28 Jun 2026 06:58:08 +0530</lastBuildDate><atom:link href="https://arunrocks.com/tags/general/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>The Internet needs more You</title>
      <link>https://arunrocks.com/the-internet-needs-more-you/</link>
      <pubDate>Sun, 28 Jun 2026 06:58:08 +0530</pubDate>
      
      <guid>https://arunrocks.com/the-internet-needs-more-you/</guid>
      <description>&lt;p&gt;Something happened to the internet around 2018.&lt;/p&gt;
&lt;p&gt;It didn&amp;rsquo;t happen overnight. It crept in slowly. The way a room gets messier until one day you can&amp;rsquo;t find anything.&lt;/p&gt;
&lt;p&gt;First, tweets became threads. A format built for brevity stretched into multi-part essays, because engagement algorithms rewarded length and click-through. Writers who had something real to say were forced to perform it in a format that wasn&amp;rsquo;t built for them.&lt;/p&gt;
&lt;p&gt;Then the feeds went algorithmic. You stopped seeing what you chose to follow. You started seeing what platforms decided you &lt;em&gt;should&lt;/em&gt; see — calibrated not for your curiosity, but for your outrage, your anxiety, your impulse to keep scrolling. The deliberate curation you&amp;rsquo;d built, the blogs you&amp;rsquo;d bookmarked, the writers you&amp;rsquo;d subscribed to were all quietly buried.&lt;/p&gt;
&lt;div data-pullquote=&#34;The internet has become extraordinarily good at producing content and increasingly bad at producing thought.&#34;&gt;
&lt;/div&gt;
&lt;p&gt;Content got commercialized. Every post became a funnel. Every newsletter became a pitch. Personal blogs quietly became brand strategy. Writing because you had something to say, without a conversion goal attached, started feeling almost quaint.&lt;/p&gt;
&lt;p&gt;And then came the LLMs.&lt;/p&gt;
&lt;p&gt;There are now over 600 million blogs on the internet. Seven and a half million posts are published every single day. And yet fewer than 10% of them generate any meaningful traffic. The irony is that never has more been written, and never has less of it said anything.&lt;/p&gt;
&lt;p&gt;Readers are tired of it too.&lt;/p&gt;
&lt;p&gt;The indie web is slowly staging a comeback. People are returning to personal sites, RSS readers, and hand-curated blogrolls — not out of nostalgia, but because the algorithmic feed has failed them. Studies show 83% of internet users still regularly read blogs. Newsletter platforms are seeing explosive growth in readers actively seeking out voices they trust — moving inside platforms to find writers, rather than waiting for algorithms to surface them.&lt;/p&gt;
&lt;p&gt;The audience exists. It&amp;rsquo;s waiting for something worth reading.&lt;/p&gt;
&lt;p&gt;The personal voice has become the scarcest resource on the internet.&lt;/p&gt;
&lt;p&gt;Not because humans stopped having opinions — but because the dominant platforms trained us to sand them down. To optimize for reach. To ask &lt;em&gt;&amp;ldquo;will this perform?&amp;rdquo;&lt;/em&gt; before asking &lt;em&gt;&amp;ldquo;is this true?&amp;rdquo;&lt;/em&gt; The result is a vast, fast-moving river of content that sounds like everything and means nothing.&lt;/p&gt;
&lt;p&gt;I know this because I&amp;rsquo;ve lived the alternative.&lt;/p&gt;
&lt;p&gt;In 2013, after a Django talk at PyCon India, someone asked me whether the framework would ever adapt to Single Page Applications. I gave the best answer I could in the moment — which wasn&amp;rsquo;t a very good one. But the question wouldn&amp;rsquo;t leave me alone. A few days later, I sat down not to publish something impressive, but to figure out what I actually thought. I reached for analogies from my game programming days. I followed threads I wasn&amp;rsquo;t sure would go anywhere. I wrote honestly about Django&amp;rsquo;s genuine shortcomings, something a promotional post would never do. I wrote my way toward an answer I hadn&amp;rsquo;t had at the conference.&lt;/p&gt;
&lt;p&gt;A PyCon attendee posted it to Hacker News. The next morning I woke up to find it sitting at #5 on the front page. I hadn&amp;rsquo;t optimized for anything. I&amp;rsquo;d thought out loud, honestly, in public. It turned out a lot of developers were sitting with the same unresolved question. That post is still one of the most-read things I&amp;rsquo;ve written. The patterns I worked out in it eventually found their way into my Django book.&lt;/p&gt;
&lt;p&gt;No algorithm put it there. No content strategy. Just a question I couldn&amp;rsquo;t answer and the willingness to work through it in front of strangers.&lt;/p&gt;
&lt;p&gt;A blog is where that kind of thinking lives. Not polished takes. Not hot angles engineered for sharing. The real thing: specific, from a specific person, in a way no language model can replicate because it comes from a life actually lived and a mind genuinely at work.&lt;/p&gt;
&lt;p&gt;So this is me, restarting.&lt;/p&gt;
&lt;p&gt;Not because blogging is trending. Not because I ran the numbers on organic reach. But because I have things to say that deserve more than 280 characters and less than an AI Overview.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve been sitting on a half-written post, an old blog that went quiet, or an idea you&amp;rsquo;ve been carrying around for months, then this is your signal.&lt;/p&gt;
&lt;p&gt;The internet doesn&amp;rsquo;t need more content. It needs more &lt;em&gt;you&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hi, I&amp;rsquo;m Arun. Human.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Battling Procrastination</title>
      <link>https://arunrocks.com/battling-procrastination/</link>
      <pubDate>Thu, 26 Aug 2021 16:56:27 +0530</pubDate>
      
      <guid>https://arunrocks.com/battling-procrastination/</guid>
      <description>&lt;p&gt;I used to think of Procrastination as a villain. If I had to complete a task before a deadline next week, I would not start work until the deadline gets uncomfortably close. The work ends up being more rushed than if I had used the entire week. Procrastination often robs the opportunity of producing better quality work.&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;Is Procrastination our mind’s defense mechanism against attempting to solve poorly understood problems?&#34;&gt;
&lt;/div&gt;
&lt;p&gt;I do not sense Procrastination as an urge or a feeling. It is rather the absence of the feelings like I &lt;em&gt;need&lt;/em&gt; to start working on something. Frankly, it is also the knowledge that I &lt;em&gt;could&lt;/em&gt; start but probably not now. To procrastinate is both a passive activity where I am not thinking about a task due for the future and an active choice to work on &lt;em&gt;seemingly&lt;/em&gt; more urgent tasks due in the near future. Hence, a vicious circle.&lt;/p&gt;
&lt;p&gt;As I get older, I realize that time is not as plentiful and readily available resource anymore. There are work and family commitments that leave only islands of time in my daily calendar. The ability to pull an all-nighter is not practical as you age since a sleep deficit cannot be easily overcome anymore. So delaying tasks often means unfinished tasks or lost opportunities. Procrastination has become a more urgent problem for me than ever.&lt;/p&gt;
&lt;p&gt;But again, it is not accurate to always characterize Procrastination as a villain. There are times when I found delaying on a creative work helped me find better ideas than I would have if I had started earlier. ‘Sleeping on a problem’ can be surprisingly effective for finding a fresh perspective for complex issues. Most creative people do not progress at a steady rate instead they work in inspired sprints and take breaks in between.&lt;/p&gt;
&lt;p&gt;So forcing oneself to work when your mind is not ready is not very useful. Is Procrastination our mind’s defense mechanism against attempting to solve poorly understood problems? Maybe. This is why there is no one-size-fits-all solution to everyone’s Procrastination problems.&lt;/p&gt;
&lt;p&gt;But I will share some of my techniques below that have helped me solve this problem to a large degree.&lt;/p&gt;
&lt;h3 id=&#34;digital-minimalism&#34;&gt;Digital Minimalism&lt;/h3&gt;
&lt;p&gt;Most of us spend an incredible amount of time on our smartphones. Many apps are designed to hook you into spending the most amount of your time so that they can monetize it effectively. Watch out for such apps. In my experience these apps are of the following kinds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Social networking apps:&lt;/strong&gt; e.g. Facebook, Instagram, WhatsApp, Twitter. I have uninstalled most of them except WhatsApp and Twitter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entertainment apps:&lt;/strong&gt; e.g. YouTube, Netflix, Amazon Prime, Games. I watch only highly recommended or very promising content. I set aside weekends and holidays for movies or longer shows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;News apps:&lt;/strong&gt; e.g. Hacker News, Reddit, Newspapers. These are essential to keep myself updated but it is very easy to get lost in rabbit holes and &lt;a href=&#34;https://www.health.com/mind-body/what-is-doomscrolling&#34;&gt;doom scrolling&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your list of apps might be different. Now most phones come with &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.google.android.apps.wellbeing&amp;amp;hl=en_US&amp;amp;gl=US&#34;&gt;well being apps&lt;/a&gt; that tell you how many times and how long you use each app. Start from that and do a self evaluation of whether you want to spend so much time on each app. Turn off notifications from all apps except the ones you really, really need.&lt;/p&gt;
&lt;p&gt;Today your time is a precious resource that must be protected from or mindfully shared with such apps. So it is not enough to practice self-control, you might need to modify your environment by uninstalling the least essential ones or time limit your access to such apps.&lt;/p&gt;
&lt;p&gt;I saved a lot of time everyday by practicing digital minimalism. Procrastination is also reduced due to less availability of such easy time sinks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended Reading:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3DaENvb&#34;&gt;Digital Minimalism: Choosing a Focused Life in a Noisy World&lt;/a&gt; - Helps you understand why you need to minimize digital stuff&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3sPnw5N&#34;&gt;Atomic Habits: An Easy &amp;amp; Proven Way to Build Good Habits &amp;amp; Break Bad Ones&lt;/a&gt; Systematic changes rather than big bang approaches to bring change&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;paper-todo-lists&#34;&gt;Paper TODO lists&lt;/h3&gt;
&lt;p&gt;There are a million TODO apps. They are all horrible. Because any digital device has a notification or a tempting app waiting for you even if you have followed my advice of turning off most notifications.&lt;/p&gt;
&lt;p&gt;Paper is the best alternative. After trying all sorts of approaches I have settled on writing my daily TODO in a A5 size notebook. The hardest part is to build a daily habit of opening the notebook and groom your TODO list. But it is worth it.&lt;/p&gt;
&lt;p&gt;Paper has the following advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Avoids distractions&lt;/strong&gt;: Remember taking your phone for noting down something, getting sidetracked into several apps and eventually forgetting why you took the phone in the first place?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Writing down helps remember&lt;/strong&gt;: To me writing with a pen is slower than typing. But that deliberate process of writing helps me remember better than typing. Keeping TODO list items in your memory is important because most of the planning and replanning of everyday tasks happens in your head.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spatial memory&lt;/strong&gt;: Sometimes I remember that I wrote something 3 months back in my notebook and can recall specifics like it was on the left side, written in red ink or had a funny Peanuts doodle next to it. Sure it is not easily searchable by keywords. But the way my memory works, it is still retrievable and a lot more likely to be retained in my mind.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fun and Creative&lt;/strong&gt;: Try adding a funny doodle next to an item in a TODO app. Or try drawing the headline of an upcoming fun event in balloon letters. Paper has no limitations to your creativity. Check out galleries of Bullet Journalists. Some are probably procrastinating but a little bit of creativity is so inspiring.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Recommended Reading:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://bulletjournal.com/pages/learn&#34;&gt;Bullet Journal - Basics&lt;/a&gt; - I use a slightly modified bullet journaling method to manage my TODOs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;timeboxing&#34;&gt;Timeboxing&lt;/h3&gt;
&lt;p&gt;Imagine you somehow manage to start working on a project several days in advance. One hour later, to your extreme frustration - the page is still blank. This paradox of having abundant time yet no progress can be understood if you know the Parkinson&amp;rsquo;s law - “work expands so as to fill the time available for its completion”.&lt;/p&gt;
&lt;p&gt;I found the best way to tackle this problem is to use timeboxing. Take any project and break it down into clear and actionable tasks that have a limited time to complete. Some tasks might seem clear but could be complex and involve multiple steps. For example,  “Write an Essay” can be split into “Research”, “Outline”, “Draft” and “Review” tasks.&lt;/p&gt;
&lt;p&gt;Studies &lt;a href=&#34;https://hbr.org/2018/12/how-timeboxing-works-and-why-it-will-make-you-more-productive&#34;&gt;show&lt;/a&gt; that time-boxing is the most effective way to beat Procrastination. Just the act of dedicating time to a task ensures clarity and focus. I find the limited time aspect of time boxing to be simultaneously reliving and motivating. Since there is an internal deadline I have to meet, I avoid the trap of time abundance.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/timeboxing.jpg&#34; alt=&#34;Timeboxing in a Journal&#34;  title=&#34;Here is how a day looks like with some dummy tasks in my bullet journal (Yeah I love to maximize space usage).&#34;  width=1000 height=&#34;462&#34;  /&gt;
    &lt;figcaption&gt;Here is how a day looks like with some dummy tasks in my bullet journal (Yeah I love to maximize space usage).&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;From my experience here are a number of Do’s and Don’ts to follow while time-boxing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Don’t pack your day with work&lt;/strong&gt;. Find ‘recharge time` in between tasks to recharge your batteries throughout the day.  Coffee breaks, walks, meditation (more on that below), fooling around or simply sitting idle. I prefer 30 mins breaks between every 2 hours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t aim for a lot in one day&lt;/strong&gt;. Stick to three significant tasks for the day. Everything else is a bonus.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t be too rigid about the timings&lt;/strong&gt;. Be flexible. They are boxes, they can be moved around!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t be fixed in a spot or fixated on a device&lt;/strong&gt;. Try a change of scenery every few minutes. For example, after 2 hours of working on the laptop, avoid taking a break by watching a video on the same screen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do revisit your old timeboxes&lt;/strong&gt;. Improve your estimates by reflecting on older gues-stimates and comparing with the actual time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do recognize your work&lt;/strong&gt;. At end end of the day:
&lt;ol&gt;
&lt;li&gt;Tick off every task you finished to reward yourself for completing them.&lt;/li&gt;
&lt;li&gt;Write down things you did but did not plan for. Then tick them off.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Recommended Reading:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3sNpgwt&#34;&gt;Rest: Why You Get More Done When You Work Less&lt;/a&gt;: A required reading on why you need to plan your day with less productive activities than you think.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;mindfulness&#34;&gt;Mindfulness&lt;/h3&gt;
&lt;p&gt;I have been practicing mindful meditation for the past 3 years. It has been extremely effective in reducing my habit of procrastinating. It is an effective tool with surprising real world benefits.&lt;/p&gt;
&lt;p&gt;Like many people, I had a lot of misconceptions about mediation. There are many kinds of meditation. The vipassana approach of meditation that I follow is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Non-religious&lt;/strong&gt; - you are not chanting any mantras&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not about concentrating hard&lt;/strong&gt; - although it may improve your focus, the goals are different.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not time consuming&lt;/strong&gt; - you can do just 10 minutes per day although I find 20 mins more effective.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not done in a perfectly silent environment&lt;/strong&gt; - it is possible to meditate in any environment. If noise is affecting you in the beginning, get noise cancelling headphones or earplugs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It might not be clear how meditation is effective in managing your work. I found it helps me respond rather than react to situations. It is like a superpower to slow down time (&lt;a href=&#34;https://www.youtube.com/watch?v=T9GFyZ5LREQ&#34;&gt;QuickSilver&lt;/a&gt;?). Then I can pause and objectively evaluate the situation.&lt;/p&gt;
&lt;p&gt;For example, I will begin to notice that feeling of anxiety when I think of cleaning my desk. It is due to the fact I don’t have my bookshelf organized to keep all the books lying around. Organizing my small bookshelf means donating some books and that means connecting with my bibliophile friend whom I haven’t spoken to in a while. Instead I decided to take a break (and relieve my anxiety) to watch a comedy special on Netflix. Sounds like a lot to unpack doesn’t it?&lt;/p&gt;
&lt;p&gt;This brings us to the question that we never answered - Why do we procrastinate? Unlike what experts used to think, it is not a self-discipline problem. It is mostly an emotional problem. There are different kinds of procrastination like passive and active types. So it is important to introspect and understand what is blocking you. Mindfulness helps you immensely in identifying the root cause.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommended reading:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2XM5Uwc&#34;&gt;Mindfulness in Plain English&lt;/a&gt; - Best introduction to mindful meditation&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2UMOnmD&#34;&gt;The Psychology of Procrastination: Understand Your Habits, Find Motivation, and Get Things Done&lt;/a&gt; - Great book to understand the modern scientific view of the causes of procrastination&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;summary&#34;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Procrastination should not be seen as the problem but a symptom. It needs to be addressed or it will start preventing you from reaching your goals. I have a few techniques that have worked for me over the last few years. I am reasonably productive following them diligently. Hope you will be too.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Some affiliate links are present in this article. Would not impact you but would help sustain the blog.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fitting a Django Application in One File</title>
      <link>https://arunrocks.com/django-application-in-one-file/</link>
      <pubDate>Wed, 09 Dec 2020 22:54:50 +0530</pubDate>
      
      <guid>https://arunrocks.com/django-application-in-one-file/</guid>
      <description>&lt;p&gt;Earlier this week, Anthony a french economics university student wanted to talk to me over Zoom about my &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;ray tracer tutorials&lt;/a&gt;. He and his friend were new to Python but were excited to implement their own ray tracer after following my videos. One of the questions that popped up in the conversation was - &amp;ldquo;Can we put all the classes in one file instead of breaking it into individual files per class?&amp;rdquo;. I said, &amp;ldquo;Of course&amp;rdquo; and noticed a wave of relief in their faces. In fact, I explained, my earlier implementation was all in one file and later broken up for better pedagogy.&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;It might be amusing to some Django developers that we will not start with the startproject command.&#34;&gt;
&lt;/div&gt;
&lt;p&gt;But the charm of an entire project in a single file is compelling. I remember seeing a Sinatra web application a few years ago containing the entire application and assets like HTML templates and CSS in a single file. Presenting all the components in the same file gave a complete high-level overview of the project by simply scrolling up and down.&lt;/p&gt;
&lt;p&gt;Normally, at this point, someone would suggest a microframework. But it is not that easy.&lt;/p&gt;
&lt;h2 id=&#34;microframeworks&#34;&gt;Microframeworks&lt;/h2&gt;
&lt;p&gt;Microframeworks take a minimalistic approach by omitting certain components or directing you to a few recommended components. For instance, &lt;a href=&#34;https://bottlepy.org/docs/dev/&#34;&gt;Bottle&lt;/a&gt; contains basic form handling capabilities but has no protection against &lt;a href=&#34;https://www.wikiwand.com/en/Cross-site_request_forgery&#34;&gt;CSRF&lt;/a&gt; or &lt;a href=&#34;https://www.wikiwand.com/en/Clickjacking&#34;&gt;clickjacking&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So the approach is generally to use another library like &lt;a href=&#34;https://pypi.org/project/bottle-utils-csrf/&#34;&gt;bottle-utils-csrf&lt;/a&gt;. This leaves the task of integration to the developer. This is not to pooh-pooh tiny web frameworks. I love the idea (especially Bottle which I think is really cute). But for public facing sites, I prefer the safety and convenience of Django.&lt;/p&gt;
&lt;p&gt;So I am tempted to try this one-file trick in Django. Let’s try to make a non-trivial web application with forms, templates and images. How does one go about doing something like that?&lt;/p&gt;
&lt;p&gt;Note: if you prefer to watch the video version, click on the video below:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/7XNChGGoBf0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;h2 id=&#34;django-applications-in-one-file&#34;&gt;Django Applications in One File&lt;/h2&gt;
&lt;h3 id=&#34;minimal&#34;&gt;Minimal&lt;/h3&gt;
&lt;p&gt;Let’s start small by creating a minimal Hello World application in Django. It might be amusing to some Django developers that we will not start with the &lt;code&gt;startproject&lt;/code&gt; command. In fact, it is not necessary for Django to work at all. All that initial directory structure and files like settings.py are for your convenience.&lt;/p&gt;
&lt;p&gt;First, create a simple file called &lt;code&gt;app.py&lt;/code&gt; with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.conf&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.urls&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.http&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# For debugging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;a-bad-secret&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Insecure! change this&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ROOT_URLCONF&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Welcome!&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;urlpatterns&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.core.management&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;execute_from_command_line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;execute_from_command_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yes, that&amp;rsquo;s all you need. There are some bad practices like hard coding the secret key (easily fixed). But the sheer elegance of everything being in hardly a screenful is quite rewarding.&lt;/p&gt;
&lt;p&gt;The command to run this file is: &lt;code&gt;python app.py runserver 8080&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now we will skip a couple of steps (they are in the video) and move on to a simple &amp;ldquo;Coming Soon&amp;rdquo; landing page.&lt;/p&gt;
&lt;h3 id=&#34;coming-soon-application&#34;&gt;Coming Soon Application&lt;/h3&gt;
&lt;p&gt;The idea of a coming-soon page is to gauge interest in a product before it is released. Such pages must have a clear call to action (CTA) like asking for your email. Ideally it should have minimum friction and yet collect all the relevant information.&lt;/p&gt;
&lt;p&gt;Let’s look at my updated app.py:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.conf&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.urls&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.http&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponseRedirect&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.core.wsgi&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_wsgi_application&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.template&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RequestContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Template&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;CSV_LIST&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;thelist.csv&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;settings&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;configure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;DEBUG&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ALLOWED_HOSTS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Disable host header validation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;ROOT_URLCONF&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;SECRET_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SECRET_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;a-bad-secret&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;TEMPLATES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;BACKEND&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;django.template.backends.django.DjangoTemplates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;MIDDLEWARE_CLASSES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;s2&#34;&gt;&amp;#34;django.middleware.common.CommonMiddleware&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;s2&#34;&gt;&amp;#34;django.middleware.csrf.CsrfViewMiddleware&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;s2&#34;&gt;&amp;#34;django.middleware.clickjacking.XFrameOptionsMiddleware&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;EnlistForm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EmailField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;required&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;label&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;widget&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EmailInput&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attrs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;placeholder&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Email&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;referrer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CharField&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;required&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;widget&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;forms&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HiddenInput&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;form&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EnlistForm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;POST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_valid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cleaned_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;n&#34;&gt;referrer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cleaned_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;META&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REMOTE_ADDR&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Got email of &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CSV_LIST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;csv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            	&lt;span class=&#34;n&#34;&gt;csv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;referrer&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponseRedirect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/thanks/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;form&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EnlistForm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;initial&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;META&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP_REFERER&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RequestContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Sign up for early access&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;form&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MAIN_HTML&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;thanks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RequestContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    	&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Thank you for signing up. We will contact you!&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;form&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MAIN_HTML&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;urlpatterns&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;thanks/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;thanks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_wsgi_application&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;MAIN_HTML&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Template&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;lt;head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;title&amp;gt;Coming Soon | Flying Cars&amp;lt;/title&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;meta name=&amp;#34;viewport&amp;#34; content=&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	@import url(&amp;#39;https://fonts.googleapis.com/css2?family=Exo:wght@400;500;600;700;800;900&amp;amp;display=swap&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	*{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	margin: 0;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	padding: 0;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	box-sizing: border-box;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	font-family: &amp;#39;Exo&amp;#39;, sans-serif;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	html,body{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	display: grid;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	height: 100%;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	width: 100%;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	place-items: center;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	background-color: #343434;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	/* Thanks to Hero Patterns for the background */
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	background-image: url(&amp;#34;data:image/svg+xml,%3Csvg xmlns=&amp;#39;http://www.w3.org/2000/svg&amp;#39; viewBox=&amp;#39;0 0 56 28&amp;#39; width=&amp;#39;56&amp;#39; height=&amp;#39;28&amp;#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%3E&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;%3Cpath fill=&amp;#39;%23000000&amp;#39; fill-opacity=&amp;#39;0.4&amp;#39; d=&amp;#39;M56 26v2h-7.75c2.3-1.27 4.94-2 7.75-2zm-26 2a2 2 0 1 0-4 0h-4.09A25.98 25.98 0 0 0 0 16v-2c.67 0 1.34.02 2 .07V14a2 2 0 0 0-2-2v-2a4 4 0 0 1 3.98 3.6 28.09 28.09 0 0 1 2.8-3.86A8 8 0 0 0 0 6V4a9.99 9.99 0 0 1 8.17 4.23c.94-.95 1.96-1.83 3.03-2.63A13.98 13.98 0 0 0 0 0h7.75c2 1.1 3.73 2.63 5.1 4.45 1.12-.72 2.3-1.37 3.53-1.93A20.1 20.1 0 0 0 14.28 0h2.7c.45.56.88 1.14 1.29 1.74 1.3-.48 2.63-.87 4-1.15-.11-.2-.23-.4-.36-.59H26v.07a28.4 28.4 0 0 1 4 0V0h4.09l-.37.59c1.38.28 2.72.67 4.01 1.15.4-.6.84-1.18 1.3-1.74h2.69a20.1 20.1 0 0 0-2.1 2.52c1.23.56 2.41 1.2 3.54 1.93A16.08 16.08 0 0 1 48.25 0H56c-4.58 0-8.65 2.2-11.2 5.6 1.07.8 2.09 1.68 3.03 2.63A9.99 9.99 0 0 1 56 4v2a8 8 0 0 0-6.77 3.74c1.03 1.2 1.97 2.5 2.79 3.86A4 4 0 0 1 56 10v2a2 2 0 0 0-2 2.07 28.4 28.4 0 0 1 2-.07v2c-9.2 0-17.3 4.78-21.91 12H30zM7.75 28H0v-2c2.81 0 5.46.73 7.75 2zM56 20v2c-5.6 0-10.65 2.3-14.28 6h-2.7c4.04-4.89 10.15-8 16.98-8zm-39.03 8h-2.69C10.65 24.3 5.6 22 0 22v-2c6.83 0 12.94 3.11 16.97 8zm15.01-.4a28.09 28.09 0 0 1 2.8-3.86 8 8 0 0 0-13.55 0c1.03 1.2 1.97 2.5 2.79 3.86a4 4 0 0 1 7.96 0zm14.29-11.86c1.3-.48 2.63-.87 4-1.15a25.99 25.99 0 0 0-44.55 0c1.38.28 2.72.67 4.01 1.15a21.98 21.98 0 0 1 36.54 0zm-5.43 2.71c1.13-.72 2.3-1.37 3.54-1.93a19.98 19.98 0 0 0-32.76 0c1.23.56 2.41 1.2 3.54 1.93a15.98 15.98 0 0 1 25.68 0zm-4.67 3.78c.94-.95 1.96-1.83 3.03-2.63a13.98 13.98 0 0 0-22.4 0c1.07.8 2.09 1.68 3.03 2.63a9.99 9.99 0 0 1 16.34 0z&amp;#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%3E&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;%3C/path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%3E&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;%3C/svg&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%3E&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	::selection{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	color: #fff;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	background: #FC4782;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	.wrapper{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	color: #eee;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	max-width: 900px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	text-align: center;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	padding: 0 50px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	.signup {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	margin-top: 30px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	margin-bottom: 10px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	.content {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	margin-top: 40px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   	margin-bottom: 10px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt; 	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;/style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;lt;/head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;lt;body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;div class=&amp;#34;wrapper&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  	&amp;lt;svg width=&amp;#34;600&amp;#34; height=&amp;#34;300&amp;#34; version=&amp;#34;1.1&amp;#34; viewBox=&amp;#34;0 0 600 300&amp;#34; xmlns=&amp;#34;http://www.w3.org/2000/svg&amp;#34;&amp;gt;&amp;lt;g transform=&amp;#34;translate(0,312)&amp;#34;&amp;gt;&amp;lt;path d=&amp;#34;m218.36-289.66h163.29c29.039 0 52.417 23.378 52.417 52.417v45.564c0 29.039-23.378 52.417-52.417 52.417h-163.29c-29.039 0-52.417-23.378-52.417-52.417v-45.564c0-29.039 23.378-52.417 52.417-52.417z&amp;#34; fill=&amp;#34;#204a87&amp;#34; stop-color=&amp;#34;#000000&amp;#34; stroke=&amp;#34;#eeeeec&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34; stroke-width=&amp;#34;4&amp;#34;/&amp;gt;&amp;lt;g fill=&amp;#34;#729fcf&amp;#34; stroke=&amp;#34;#eeeeec&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34; stroke-width=&amp;#34;4&amp;#34;&amp;gt;&amp;lt;path d=&amp;#34;m240.88-162.15c21.473-37.192 42.946-74.385 64.419-111.58&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;g stroke-linecap=&amp;#34;round&amp;#34;&amp;gt;&amp;lt;path d=&amp;#34;m276.15-249.32h-72.081&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m259.9-221.32h-56.025&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m267.69-235.32h-63.714&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m370.37-162.15c-21.473-37.192-42.946-74.385-64.419-111.58&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m332-249.93h72.081&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m348.25-221.93h56.025&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m340.46-235.93h63.714&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m240.88-162.15c21.473-26.526 42.946-53.051 64.419-79.577&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;path d=&amp;#34;m370.37-162.15c-21.473-26.526-42.946-53.051-64.419-79.577&amp;#34; stop-color=&amp;#34;#000000&amp;#34;/&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;g fill=&amp;#34;#eeeeec&amp;#34;&amp;gt;&amp;lt;path d=&amp;#34;m183.74-116.06-6.3858 17.316h12.795zm-2.6568-4.6378h5.337l13.261 34.795h-4.8942l-3.1696-8.9261h-15.685l-3.1696 8.9261h-4.9641z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m222.66-120.7h4.7078v34.795h-4.7078z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m271.14-102.22q1.5149.51273 2.9365 2.1907 1.445 1.678 2.8899 4.6145l4.7777 9.5087h-5.0573l-4.4514-8.9261q-1.7246-3.4959-3.356-4.6378-1.6081-1.142-4.4048-1.142h-5.1273v14.706h-4.7078v-34.795h10.627q5.9663 0 8.9028 2.4937t2.9365 7.5278q0 3.2861-1.5382 5.4535-1.5149 2.1674-4.4281 3.0064zm-11.793-14.613v12.352h5.9196q3.4026 0 5.1273-1.5615 1.7479-1.5848 1.7479-4.6378t-1.7479-4.5912q-1.7246-1.5615-5.1273-1.5615z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m329.38-118.02v4.9641q-2.3772-2.214-5.0806-3.3094-2.6802-1.0954-5.7099-1.0954-5.9663 0-9.1358 3.659-3.1696 3.6357-3.1696 10.534 0 6.8752 3.1696 10.534 3.1696 3.6357 9.1358 3.6357 3.0297 0 5.7099-1.0954 2.7035-1.0954 5.0806-3.3094v4.9175q-2.4704 1.678-5.2438 2.517-2.7501.83901-5.8264.83901-7.9006 0-12.445-4.8243-4.5446-4.8476-4.5446-13.214 0-8.39 4.5446-13.214 4.5446-4.8476 12.445-4.8476 3.123 0 5.873.839 2.7734.8157 5.1972 2.4704z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m366.18-116.06-6.3858 17.316h12.795zm-2.6568-4.6378h5.337l13.261 34.795h-4.8942l-3.1696-8.9261h-15.685l-3.1696 8.9261h-4.9641z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;path d=&amp;#34;m421.6-102.22q1.5149.51273 2.9365 2.1907 1.445 1.678 2.8899 4.6145l4.7777 9.5087h-5.0573l-4.4514-8.9261q-1.7246-3.4959-3.356-4.6378-1.6081-1.142-4.4048-1.142h-5.1272v14.706h-4.7078v-34.795h10.627q5.9663 0 8.9028 2.4937t2.9365 7.5278q0 3.2861-1.5382 5.4535-1.5149 2.1674-4.4281 3.0064zm-11.793-14.613v12.352h5.9196q3.4026 0 5.1272-1.5615 1.7479-1.5848 1.7479-4.6378t-1.7479-4.5912q-1.7246-1.5615-5.1272-1.5615z&amp;#34; style=&amp;#34;text-decoration-color:#000000;text-decoration-line:none&amp;#34;/&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;/g&amp;gt;&amp;lt;/svg&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  	&amp;lt;h1&amp;gt;All Your Traffic Problems Solved!&amp;lt;/h1&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  	&amp;lt;h2&amp;gt;Feel the future with affordable levitating cars.&amp;lt;/h2&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  	&amp;lt;div class=&amp;#34;content&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    	{{ content }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    	{&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;% i&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;f form %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;      	&amp;lt;form action=&amp;#34;.&amp;#34; method=&amp;#34;post&amp;#34; class=&amp;#34;enlist_form&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;% c&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;srf_token %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{{ form.non_field_errors }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{{ form.email.errors }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{{ form.referrer }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{{ form.referrer.errors }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	{{ form.email }}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        	&amp;lt;button type=&amp;#34;submit&amp;#34;&amp;gt;Add Me&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;      	&amp;lt;/form&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    	{&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;% e&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;ndif %}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  	&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;	&amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;lt;/body&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;django.core.management&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;execute_from_command_line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;n&#34;&gt;execute_from_command_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Except for the absence of individual files, most of the code should be familiar to a Django developer. There is a large HTML template (including two SVG images) embedded as a string.&lt;/p&gt;
&lt;p&gt;Note that I do not use the ORM here. Django does seem to need a directory structure for that (Unless any reader could show me how to do it in a single file).&lt;/p&gt;
&lt;p&gt;Hopefully this shows how minimal Django could be. You might be able to use your favourite framework in places which you didn’t think were possible.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>3 Effective Examples of Django Async Views without Sleeping</title>
      <link>https://arunrocks.com/django-async-views-examples/</link>
      <pubDate>Tue, 01 Dec 2020 13:33:19 +0530</pubDate>
      
      <guid>https://arunrocks.com/django-async-views-examples/</guid>
      <description>&lt;p&gt;In August this year, &lt;a href=&#34;https://www.djangoproject.com/weblog/2020/aug/04/django-31-released/&#34;&gt;Django 3.1 arrived&lt;/a&gt; with support for Django async views. This was fantastic news but most people raised the obvious question &amp;ndash; What can I do with it? There have been a few tutorials about Django asynchronous views that demonstrate asynchronous execution while calling &lt;code&gt;asyncio.sleep&lt;/code&gt;. But that merely led to the refinement of the popular question &amp;ndash; What can I do with it besides &lt;strong&gt;sleep&lt;/strong&gt;-ing?&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;In Django&amp;#39;s MTV (Model Template View) architecture, Views are disproportionately more powerful than others.&#34;&gt;
&lt;/div&gt;
&lt;p&gt;The short answer is &amp;ndash; it is a very powerful technique to write efficient views. For a detailed overview of what asynchronous views are and how they can be used, keep on reading. If you are new to asynchronous support in Django and like to know more background, read my earlier article: &lt;a href=&#34;https://arunrocks.com/a-guide-to-asgi-in-django-30-and-its-performance/&#34;&gt;A Guide to ASGI in Django 3.0 and its Performance&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;django-async-views&#34;&gt;Django Async Views&lt;/h2&gt;
&lt;p&gt;Django now allows you to write views which can run asynchronously. First let&amp;rsquo;s refresh your memory by looking at a simple and minimal &lt;em&gt;synchronous&lt;/em&gt; view in Django:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Made a pretty page&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It takes a request object and returns a response object. In a real world project, a view does many things like fetching records from a database, calling a service or rendering a template. But they work synchronously or one after the other.&lt;/p&gt;
&lt;p&gt;In Django&amp;rsquo;s MTV (Model Template View) architecture, Views are disproportionately more powerful than others (I find it comparable to a controller in MVC architecture though these things are debatable). Once you enter a view you can perform almost any logic necessary to create a response. This is why Asynchronous Views are so important. It lets you do more things concurrently.&lt;/p&gt;
&lt;p&gt;It is quite easy to write an asynchronous view. For example the asynchronous version of our minimal example above would be:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;index_async&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Made a pretty page asynchronously.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a &lt;em&gt;coroutine&lt;/em&gt; rather than a function. You cannot call it directly. An event loop needs to be created to execute it. But you do not have to worry about that difference since Django takes care of all that.&lt;/p&gt;
&lt;p&gt;Note that this particular view is not invoking anything asynchronously. If Django is running in the classic WSGI mode, then a new event loop is created (automatically) to run this coroutine. So in this case, it might be slightly slower than the synchronous version. But that&amp;rsquo;s because you are not using it to run tasks concurrently.&lt;/p&gt;
&lt;p&gt;So then why bother writing asynchronous views? The limitations of synchronous views  become apparent only at a certain scale. When it comes to large scale web applications probably nothing beats FaceBook.&lt;/p&gt;
&lt;h2 id=&#34;views-at-facebook&#34;&gt;Views at Facebook&lt;/h2&gt;
&lt;p&gt;In August, Facebook &lt;a href=&#34;https://engineering.fb.com/2020/08/07/security/pysa/&#34;&gt;released a static analysis tool&lt;/a&gt; to detect and prevent security issues in Python. But what caught my eye was how the views were written in the examples they had shared. They were all async!&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# views/user.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_profile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;profile&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load_profile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;user_id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# controller/user.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load_profile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# Loads a user safely; no SQL injection&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;pictures&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load_pictures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# model/media.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load_pictures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;      SELECT *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;      FROM pictures
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;      WHERE user_id = &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;user_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;   &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# model/shared.py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;create_sql_connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that this is not Django but something similar. Currently, Django runs the database code synchronously. But that &lt;a href=&#34;https://www.aeracode.org/2018/06/04/django-async-roadmap/&#34;&gt;may change&lt;/a&gt; sometime in the future.&lt;/p&gt;
&lt;p&gt;If you think about it, it makes perfect sense. Synchronous code can be blocked while waiting for an I/O operation for several microseconds. However, its equivalent asynchronous code would not be tied up and can work on other tasks. Therefore it can handle more requests with lower latencies. More requests gives Facebook (or any other large site) the ability to handle more users on the same infrastructure.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/async-illustration-1.jpg&#34; alt=&#34;Illustration&#34;  title=&#34;Scalability Problems in the 1800s, I suppose&#34;  width=793 height=&#34;430&#34;  /&gt;
    &lt;figcaption&gt;Scalability Problems in the 1800s, I suppose&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Even if you are not close to reaching Facebook scale, you could use Python&amp;rsquo;s asyncio as a more predictable threading mechanism to run many things concurrently. A thread scheduler could interrupt in between destructive updates of shared resources leading to difficult to debug race conditions. Compared to threads, coroutines can achieve a higher level of concurrency with very less overhead.&lt;/p&gt;
&lt;h2 id=&#34;misleading-sleep-examples&#34;&gt;Misleading Sleep Examples&lt;/h2&gt;
&lt;p&gt;As I joked earlier, most of the Django async views tutorials show an example involving sleep. Even the official Django release notes had this example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;my_view&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Hello, async world!&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To a Python async guru this code might indicate the possibilities that were not previously possible. But to the vast majority, this code is misleading in many ways.&lt;/p&gt;
&lt;p&gt;Firstly, the sleep happening synchronously or asynchronously makes no difference to the end user. The poor chap who just opened the URL linked to that view will have to wait for 0.5 seconds before it returns a cheeky &amp;ldquo;Hello, async world!&amp;rdquo;. If you are a complete novice, you may have expected an immediate reply and somehow the &amp;ldquo;hello&amp;rdquo; greeting to appear asynchronously half a second later. Of course, that sounds silly but then what is this example trying to do compared to a synchronous &lt;code&gt;time.sleep()&lt;/code&gt; inside a view?&lt;/p&gt;
&lt;p&gt;The answer is, as with most things in the asyncio world, in the &lt;a href=&#34;https://docs.python.org/3/library/asyncio-eventloop.html&#34;&gt;event loop&lt;/a&gt;. If the event loop had some other task waiting to be run then that half second window would give it an opportunity to run that. Note that it may take longer than that window to complete. &lt;em&gt;&lt;a href=&#34;https://arunrocks.com/get-started-with-async-and-await/&#34;&gt;Cooperative Multithreading&lt;/a&gt;&lt;/em&gt; assumes that everyone works quickly and hands over the control promptly back to the event loop.&lt;/p&gt;
&lt;p&gt;Secondly, it does not seem to accomplish anything useful. Some command-line interfaces use sleep to give enough time for users to read a message before disappearing. But it is the opposite for web applications - a faster response from the web server is the key to a better user experience. So by slowing the response what are we trying to demonstrate in such examples?&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/async-illustration-2.jpg&#34; alt=&#34;Illustration&#34;  title=&#34;Letting them Sleep Would Be Better Idea&#34;  width=659 height=&#34;560&#34;  /&gt;
    &lt;figcaption&gt;Letting them Sleep Would Be Better Idea&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;The best explanation for such simplified examples I can give is &lt;em&gt;convenience&lt;/em&gt;. It needs a bit more setup to show examples which really need asynchronous support. That&amp;rsquo;s what we are trying to explore here.&lt;/p&gt;
&lt;h2 id=&#34;better-examples&#34;&gt;Better examples&lt;/h2&gt;
&lt;p&gt;A rule of thumb to remember before writing an asynchronous view is to check if it is &lt;a href=&#34;https://en.wikipedia.org/wiki/I/O_bound&#34;&gt;I/O bound&lt;/a&gt; or &lt;a href=&#34;https://en.wikipedia.org/wiki/CPU-bound&#34;&gt;CPU-bound&lt;/a&gt;. A view which spends most of the time in a CPU-bound activity for e.g. matrix multiplication or image manipulation would really not benefit from rewriting them to async views. You should be focussing on the I/O bound activities.&lt;/p&gt;
&lt;h3 id=&#34;invoking-microservices&#34;&gt;Invoking Microservices&lt;/h3&gt;
&lt;p&gt;Most large web applications are moving away from a monolithic architecture to one composed of many microservices. Rendering a view might require the results of many internal or external services.&lt;/p&gt;
&lt;p&gt;In our example, an ecommerce site for books renders its front page - like most popular sites - tailored to the logged in user by displaying recommended books. The recommendation engine is typically implemented as a separate microservice that makes recommendations based on past buying history and perhaps a bit of machine learning by understanding how successful its past recommendations were.&lt;/p&gt;
&lt;p&gt;In this case, we also need the results of another microservice that decides which promotional banners to display as a rotating banner or slideshow to the user. These banners are not tailored to the logged in user but change depending on the items currently on sale (active promotional campaign) or date.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at how a synchronous version of such a page might look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;sync_home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;Display homepage by calling two services synchronously&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;promo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RECCO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;recco&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RequestError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;An error occurred while requesting &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;index.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here instead of the popular Python &lt;a href=&#34;https://requests.readthedocs.io/en/master/&#34;&gt;requests&lt;/a&gt; library we are using the &lt;a href=&#34;https://www.python-httpx.org/&#34;&gt;httpx&lt;/a&gt; library because it supports making synchronous and asynchronous web requests. The interface is almost identical.&lt;/p&gt;
&lt;p&gt;The problem with this view is that the time taken to invoke these services add up since they happen sequentially. The Python process is suspended until the first service responds which could take a long time in a worst case scenario.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try to run them concurrently using a simplistic (and ineffective) await call:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;async_home_inefficient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;Display homepage by calling two awaitables synchronously (does NOT run concurrently)&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AsyncClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;promo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RECCO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;recco&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RequestError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;An error occurred while requesting &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;index.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice that the view has changed from a function to a coroutine (due to &lt;code&gt;async def&lt;/code&gt; keyword). Also note that there are two places where we await for a response from each of the services. You don&amp;rsquo;t have to try to understand every line here, as we will explain with a better example.&lt;/p&gt;
&lt;p&gt;Interestingly, this view does not work concurrently and takes the same amount of time as the synchronous view. If you are familiar with asynchronous programming, you might have guessed that simply awaiting a coroutine does not make it run other things concurrently, you will just yield control back to the event loop. The view still gets suspended.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at a proper way to run things concurrently:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;async_home&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;Display homepage by calling two services asynchronously (proper concurrency)&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AsyncClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;response_p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response_r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gather&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RECCO_SERVICE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response_p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;promo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response_p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response_r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;recco&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response_r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;httpx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RequestError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;An error occurred while requesting &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;index.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If the two services we are calling have similar response times, then this view should complete in _half _the time compared to the synchronous version. This is because the calls happen concurrently as we would want.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s try to understand what is happening here. There is an outer try&amp;hellip;except block to catch request errors while making either of the HTTP calls. Then there is an inner async&amp;hellip;with block which gives a context having the client object.&lt;/p&gt;
&lt;p&gt;The most important line is one with the asyncio.gather call taking the coroutines created by the two &lt;code&gt;client.get&lt;/code&gt; calls. The gather call will execute them concurrently and return only when both of them are completed. The result would be a tuple of responses which we will unpack into two variables &lt;code&gt;response_p&lt;/code&gt; and &lt;code&gt;response_r&lt;/code&gt;. If there were no errors, these responses are populated in the context sent for template rendering.&lt;/p&gt;
&lt;p&gt;Microservices are typically internal to the organization hence the response times are low and less variable. Yet, it is never a good idea to rely solely on synchronous calls for communicating between microservices. As the dependencies between services increases, it creates long chains of request and response calls. Such chains can slow down services.&lt;/p&gt;
&lt;h4 id=&#34;why-live-scraping-is-bad&#34;&gt;Why Live Scraping is Bad&lt;/h4&gt;
&lt;p&gt;We need to address web scraping because so many asyncio examples use them. I am referring to cases where multiple external websites or pages within a website are concurrently fetched and scraped for information like live stock market (or bitcoin) prices. The implementation would be very similar to what we saw in the Microservices example.&lt;/p&gt;
&lt;p&gt;But this is very risky since a view should return a response to the user as quickly as possible. So trying to fetch external sites which have variable response times or throttling mechanisms could be a poor user experience or even worse a browser timeout. Since microservice calls are typically internal, response times can be controlled with proper SLAs.&lt;/p&gt;
&lt;p&gt;Ideally, scraping should be done in a separate process scheduled to run periodically (using &lt;a href=&#34;https://docs.celeryproject.org/en/stable/django/&#34;&gt;celery&lt;/a&gt; or &lt;a href=&#34;https://python-rq.org/&#34;&gt;rq&lt;/a&gt;). The view should simply pick up the scraped values and present them to the users.&lt;/p&gt;
&lt;h3 id=&#34;serving-files&#34;&gt;Serving Files&lt;/h3&gt;
&lt;p&gt;Django addresses the problem of serving files by trying hard not to do it itself. This makes sense from a &amp;ldquo;Do not reinvent the wheel&amp;rdquo; perspective. After all, there are several better solutions to serve static files like &lt;a href=&#34;https://www.nginx.com/&#34;&gt;nginx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/async-illustration-3.jpg&#34; alt=&#34;Illustration&#34;  title=&#34;&amp;#39;Serving simultaneously is not for everyone&amp;#39;&#34;  width=716 height=&#34;627&#34;  /&gt;
    &lt;figcaption&gt;&amp;#39;Serving simultaneously is not for everyone&amp;#39;&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;But often we need to serve files with dynamic content. Files often reside in a (slower) disk-based storage (we now have much faster SSDs). While this file operation is quite easy to accomplish with Python, it could be expensive in terms of performance for large files. Regardless of the file&amp;rsquo;s size, this is a potentially blocking I/O operation that could potentially be used for running another task concurrently.&lt;/p&gt;
&lt;p&gt;Imagine we need to serve a PDF certificate in a Django view. However the date and time of downloading the certificate needs to be stored in the metadata of the PDF file, for some reason (possibly for identification and validation).&lt;/p&gt;
&lt;p&gt;We will use the &lt;a href=&#34;https://pypi.org/project/aiofiles/&#34;&gt;aiofiles&lt;/a&gt; library here for asynchronous file I/O. The API is almost the same as the familiar Python&amp;rsquo;s built-in file API. Here is how the asynchronous view could be written:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;serve_certificate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isoformat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content_type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;application/pdf&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Disposition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;attachment; filename=certificate.pdf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiofiles&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;homepage/pdfs/certificate-template.pdf&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;%timestamp%&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This example illustrates why we need asynchronous template rendering in Django. But until that gets implemented, you could use aiofiles library to pull local files without skipping a beat.&lt;/p&gt;
&lt;p&gt;There are downsides to directly using local files instead of Django&amp;rsquo;s &lt;a href=&#34;https://docs.djangoproject.com/en/3.1/ref/contrib/staticfiles/&#34;&gt;staticfiles&lt;/a&gt;. In the future, when you migrate to a different storage space like Amazon S3, make sure you adapt your code accordingly.&lt;/p&gt;
&lt;h3 id=&#34;handling-uploads&#34;&gt;Handling Uploads&lt;/h3&gt;
&lt;p&gt;On the flip side, uploading a file is also a potentially long, blocking operation. For security and organizational reasons, Django&lt;a href=&#34;https://docs.djangoproject.com/en/3.1/ref/files/&#34;&gt; stores all uploaded content&lt;/a&gt; into a separate &amp;lsquo;media&amp;rsquo; directory.&lt;/p&gt;
&lt;p&gt;If you have a form that allows uploading a file, then we need to anticipate that some pesky user would upload an impossibly large one. Thankfully Django passes the file to the view as chunks of a certain size. Combined with aiofile&amp;rsquo;s ability to write a file asynchronously, we could support highly concurrent uploads.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;handle_uploaded_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiofiles&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;uploads/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wb+&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;destination&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chunk&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chunks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;destination&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chunk&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;async_uploader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UploadFileForm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;POST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FILES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_valid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle_uploaded_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FILES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HttpResponseRedirect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UploadFileForm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;upload.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;form&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;form&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again this is circumventing Django&amp;rsquo;s default file upload mechanism, so you need to be careful about the security implications.&lt;/p&gt;
&lt;h2 id=&#34;where-to-use&#34;&gt;Where To Use&lt;/h2&gt;
&lt;p&gt;Django Async project has full backward compatibility as one of its main goals. So you can continue to use your old synchronous views without rewriting them into async. Asynchronous views are not a panacea for all performance issues, so most projects will still continue to use synchronous code since they are quite straightforward to reason about.&lt;/p&gt;
&lt;p&gt;In fact, you can use both async and sync views in the same project. Django will take care of calling the view in the appropriate manner. However, if you are using async views it is recommended to deploy the application on ASGI servers.&lt;/p&gt;
&lt;p&gt;This gives you the flexibility to try asynchronous views gradually especially for I/O intensive work. You need to be careful to pick only async libraries or mix them with sync carefully (use the &lt;a href=&#34;https://docs.djangoproject.com/en/3.1/topics/async/#async-to-sync&#34;&gt;async_to_sync&lt;/a&gt; and &lt;a href=&#34;https://docs.djangoproject.com/en/3.1/topics/async/#sync-to-async&#34;&gt;sync_to_async&lt;/a&gt; adaptors).&lt;/p&gt;
&lt;p&gt;Hopefully this writeup gave you some ideas.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;a href=&#34;https://avilpage.com/&#34;&gt;Chillar Anand&lt;/a&gt; and &lt;a href=&#34;https://twitter.com/agrawalritesh_&#34;&gt;Ritesh Agrawal&lt;/a&gt; for reviewing this post. All illustrations courtesy of &lt;a href=&#34;https://www.oldbookillustrations.com/&#34;&gt;Old Book Illustrations&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python (Part 6) - Show Notes of &#34;Firing All Cores&#34;</title>
      <link>https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/</link>
      <pubDate>Mon, 17 Aug 2020 12:08:10 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/&#34;&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/&#34;&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/&#34;&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/&#34;&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/&#34;&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;When it comes to code optimization, there is an overused statement about Premature Optimization. Here is the rarely-shown full quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: &lt;strong&gt;premature optimization is the root of all evil&lt;/strong&gt;. Yet we should not pass up our opportunities in that critical 3%.&amp;rdquo; &amp;ndash; Donald Knuth&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I understand this as not worrying about small optimizations all the time. It is best to focus on the areas which have the most return on (time) investment. Usually you need to do extensive performance measurements to find those areas but there are some natural places to look.&lt;/p&gt;
&lt;p&gt;So far, we have been not too concerned about performance especially when it affected readability (else we wouldn&amp;rsquo;t be writing it in Python). However, in the previous part we got a huge speedup by switching to the PyPy interpreter.&lt;/p&gt;
&lt;p&gt;To me the next big opportunity lies in using all the cores. As an experienced Python programmer, I know this means using the &lt;a href=&#34;https://docs.python.org/3/library/multiprocessing.html&#34;&gt;multiprocessing module&lt;/a&gt;. But I also need to explain why other options, notably Python threads, would not help.&lt;/p&gt;
&lt;p&gt;To demonstrate this I wrote a multi-threaded C program, a multi-threaded Python program and a multi-processing Python program - all doing the same thing. What was most entertaining was to watch the GIL in action where it allows only one thread to execute at a time.&lt;/p&gt;
&lt;h2 id=&#34;race-conditions&#34;&gt;Race Conditions&lt;/h2&gt;
&lt;p&gt;Race conditions are often explained using a bank ATM example. I think it can be explained in a non technical way using many real life scenarios. I wanted to explain it using a cooking example. It&amp;rsquo;s weird how many asynchronous and parallel concepts can be taught using what we do in the kitchen. So much so that technical job interviews can be made more effective by simply checking your culinary skills (&amp;ldquo;Sorry we don&amp;rsquo;t have a whiteboard, just a cutting board for you.&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Ideally the entire explanation should be animated. My drawing skills are decent but I cannot animate even a bouncing ball. Don&amp;rsquo;t laugh, just try it. Firstly, there are several cues that any animated object gives which can be only be detected if you watch in slow motion. &lt;a href=&#34;https://en.wikipedia.org/wiki/Twelve_basic_principles_of_animation&#34;&gt;The Twelve Principles of Animation&lt;/a&gt; is a good start.&lt;/p&gt;
&lt;p&gt;Secondly, it is a lot of work. A good animator will know how to give maximum expression with the minimum frames. Timing is also crucial in animation. Even a subtle timing error makes animations look janky or confusing. Mere mortals would need to spend days to eventually produce a 5 second clip.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/race-bakery.png&#34; alt=&#34;Race Conditions&#34;  title=&#34;Animating the Race Conditions&#34;  width=1920 height=&#34;1080&#34;  /&gt;
    &lt;figcaption&gt;Animating the Race Conditions&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;So I took the safe approach by showing a slideshow. I think it looks decent. I might post it as a separate clip on Race Conditions so that is doesn&amp;rsquo;t get lost in this video.&lt;/p&gt;
&lt;p&gt;These are the topics we will cover in this episode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction
&lt;ul&gt;
&lt;li&gt;An Embarrassingly Parallel Problems&lt;/li&gt;
&lt;li&gt;What&amp;rsquo;s a Thread?&lt;/li&gt;
&lt;li&gt;Threads in C&lt;/li&gt;
&lt;li&gt;Threads in Python&lt;/li&gt;
&lt;li&gt;Race Condition Animated&lt;/li&gt;
&lt;li&gt;Why Python has GIL&lt;/li&gt;
&lt;li&gt;Multi-processing in Python&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sub-problem: Firing All Cores&lt;/li&gt;
&lt;li&gt;Coding the solution
&lt;ul&gt;
&lt;li&gt;Command-line argument&lt;/li&gt;
&lt;li&gt;Diving pixels among processes&lt;/li&gt;
&lt;li&gt;Passing Data via Files&lt;/li&gt;
&lt;li&gt;Value for Progressbar&lt;/li&gt;
&lt;li&gt;Bug Hunting&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Performance Comparison&lt;/li&gt;
&lt;li&gt;Topics Not Covered&lt;/li&gt;
&lt;li&gt;Learning More&lt;/li&gt;
&lt;li&gt;Final Words&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the video:
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/GZ2reWs4_qY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Code for part six is tagged on the &lt;a href=&#34;https://github.com/arocks/puray/tree/episode06&#34;&gt;Puray Github project&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Books and articles that can help understand this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/3141v7j&#34;&gt;The Art of Multiprocessor Programming&lt;/a&gt; book&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2WzdwPh&#34;&gt;The Ray Tracer Challenge&lt;/a&gt; book&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://raytracing.github.io/&#34;&gt;Ray Tracing in One Weekend&lt;/a&gt; free books&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://news.developer.nvidia.com/ray-tracing-essentials-part-1-basics-of-ray-tracing/&#34;&gt;NVIDIA Ray Tracing Essentials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: References may contain affiliate links&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;This concludes the ray tracing series that I had conceived more than a year back. If you make your own ray tracer, please don&amp;rsquo;t forget to tag me.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python (Part 5) - Show Notes of &#34;Some Light Reflections&#34;</title>
      <link>https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/</link>
      <pubDate>Tue, 12 May 2020 22:08:10 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/&#34;&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/&#34;&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/&#34;&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/&#34;&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/&#34;&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;One of the fascinating ways to build a complex system like a computer is to build it from scratch using simple logic gates (a good book which shows how is &lt;a href=&#34;https://amzn.to/2YXRwQc&#34;&gt;The Elements of Computing Systems&lt;/a&gt;). Same goes for late John Conway&amp;rsquo;s &lt;a href=&#34;https://bitstorm.org/gameoflife/&#34;&gt;Game of Life&lt;/a&gt; which starts with a simple set of rules but shows very life-like behaviour. This is called &lt;a href=&#34;https://en.wikipedia.org/wiki/Emergence&#34;&gt;Emergent complexity&lt;/a&gt;. I guess the only way to understand something that seems complex is to understand its basic principles.&lt;/p&gt;
&lt;p&gt;Look carefully at the, by now familiar, image that we will be rendering by the end of this part:&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/rt05-two-balls.png&#34; alt=&#34;Render of two balls&#34;  title=&#34;Render of the two balls scene&#34;  width=1920 height=&#34;1080&#34;  /&gt;
    &lt;figcaption&gt;Render of the two balls scene&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Notice within the pinkish-purple ball there is a reflection of the red ball reflecting the pink ball. This kind of detailing that unfolds on closer inspection is what gives realistic renders its beauty. Yet it is governed by the most basic laws of Physics like the laws of reflection.&lt;/p&gt;
&lt;h2 id=&#34;reflection&#34;&gt;Reflection&lt;/h2&gt;
&lt;p&gt;The law tells us that the angle of reflection is the same as the angle of incidence. But if we apply it to the world of vectors a rather different looking formula emerges that &lt;a href=&#34;https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel&#34;&gt;could be derived&lt;/a&gt; from the very same law. The reflected ray is again traced and the process continues.&lt;/p&gt;
&lt;p&gt;If you have been following the series closely so far, then you might point out that we have already dealt with this earlier. Yes, diffuse and specular shading are special cases of a material reflecting light. But since we are now considering mirror-like reflecting surfaces it is time to look at the general formula for reflection.&lt;/p&gt;
&lt;p&gt;The computation for each pixel will now increase many fold so the overall render time will increase proportional to the maximum depth of reflections we need.&lt;/p&gt;
&lt;h2 id=&#34;procedural-materials&#34;&gt;Procedural Materials&lt;/h2&gt;
&lt;p&gt;A plainly colored object is not quite interesting so you would find even the earliest ray traced images containing a chessboard pattern:&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/rt05-angler.png&#34; alt=&#34;The Compleat Angler&#34;  title=&#34;The Compleat Angler (1978) by Turner Whitted&#34;  width=640 height=&#34;484&#34;  /&gt;
    &lt;figcaption&gt;The Compleat Angler (1978) by Turner Whitted&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;So I introduce a chessboard pattern generated procedurally into the scene. Procedural textures are fascinating and a lot of fun to make. Compared to image textures, they have almost infinite detail. Sort of like analog versus digital.&lt;/p&gt;
&lt;p&gt;The chessboard pattern&amp;rsquo;s formula is easy to guess so it is an ideal introduction. Once you start playing around there is an &lt;a href=&#34;http://www.upvector.com/?section=Tutorials&amp;amp;subsection=Intro%20to%20Procedural%20Textures&#34;&gt;entire universe of textures&lt;/a&gt; to explore with marble, Voronoi and Perlin noise patterns. Some even go to the extend of building entire scenes with only procedural textures. This is deeply satisfying but probably pointless.&lt;/p&gt;
&lt;h2 id=&#34;plugin-scenes&#34;&gt;Plugin Scenes&lt;/h2&gt;
&lt;p&gt;Most toy raytracers are happy generating their scene in the main program. But this quickly becomes frustrating when you want to render a couple of examples. The straightforward solution would be to define a scene as data say using JSON and import the scene given as an argument. This is how games like &lt;a href=&#34;https://en.wikipedia.org/wiki/Doom_(1993_video_game)&#34;&gt;Doom&lt;/a&gt; load levels.&lt;/p&gt;
&lt;p&gt;JSON, YAML and other configuration languages are deceptively simple to read but you could spend a lot of time writing them due to their tiny quirks with commas and whitespaces. It is also not suited for scenes generated procedurally which is happens quite a bit in ray tracers. You would soon wish if these languages were Turing complete. So I decided to ditch all that and use plain old Python instead.&lt;/p&gt;
&lt;p&gt;To be honest, I was not comfortable in allowing a given Python file to describe a scene. But the power and flexibility it allows is really a great tradeoff for the security. I used &lt;a href=&#34;https://docs.python.org/3/library/importlib.html&#34;&gt;importlib&lt;/a&gt; to import modules inspired by Django.&lt;/p&gt;
&lt;p&gt;I can now define a new procedural texture material class inside a scene! This makes the ray tracer quite extensible like a plugin system. I love this approach and look forward to trying this in future projects.&lt;/p&gt;
&lt;h2 id=&#34;accelerating-python&#34;&gt;Accelerating Python&lt;/h2&gt;
&lt;p&gt;Towards the end we see a dramatic 7X speedup of the ray tracer due to the use of &lt;a href=&#34;https://www.pypy.org/index.html&#34;&gt;PyPy&lt;/a&gt;. I also mention my rough rule of thumb to increase Python performance:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Processor Bound? Try Pypy. &lt;br&gt;
IO Bound? Try AsyncIO.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you are learning to improve the performance of your Python program, this would be pretty bad advice. In that case, make sure you first profile your program and identify the performance hotspots. Then try different ways to optimize those places. After you have tried all that and the performance is still bad, then you can use my rule of thumb for unconventional ways to get great results.&lt;/p&gt;
&lt;h2 id=&#34;ray-tracing-concepts&#34;&gt;Ray tracing concepts&lt;/h2&gt;
&lt;p&gt;With this part, I would have covered all the basic ray tracing concepts that I had planned to cover. The next part would be about improving the performance of the ray tracer by using multiple cores.&lt;/p&gt;
&lt;p&gt;Many have contacted me asking whether I would be covering topics like Dielectrics, Depth of Field, Anti-aliasing etc. I think there are enough books like &lt;a href=&#34;https://amzn.to/2Wt4x2s&#34;&gt;Ray Tracing Gems&lt;/a&gt; and &lt;a href=&#34;(https://amzn.to/2Aqp679)&#34;&gt;Ray Tracing in One Weekend&lt;/a&gt; which cover all that and much more. If you have followed this series then reading those books would be much easier and you would have a ready implementation to tinker with.&lt;/p&gt;
&lt;p&gt;Nevertheless, I may work on a follow-up if people find that useful and time permits. So do let me know.&lt;/p&gt;
&lt;p&gt;These are the topics we will cover in this episode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction
&lt;ul&gt;
&lt;li&gt;Laws of Reflection&lt;/li&gt;
&lt;li&gt;Stack Overflow&lt;/li&gt;
&lt;li&gt;Scene Definition&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sub-problem: Some Light Reflections&lt;/li&gt;
&lt;li&gt;Coding the solution
&lt;ul&gt;
&lt;li&gt;Chessboard Material&lt;/li&gt;
&lt;li&gt;Ground Plane&lt;/li&gt;
&lt;li&gt;Config vs Code as Config&lt;/li&gt;
&lt;li&gt;Speedup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the video:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/bB0KFHB5KGc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Code for part five is tagged on the &lt;a href=&#34;https://github.com/arocks/puray/tree/episode05&#34;&gt;Puray Github project&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Books and articles that can help understand this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel&#34;&gt;Derive Vector Reflection Formula&lt;/a&gt;: Understand how the formula can be derived from the laws of reflection.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Further reading on ray tracing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;(https://amzn.to/2Aqp679)&#34;&gt;Ray Tracing in One Weekend&lt;/a&gt; - The first in a series of minibooks. This is followed by two more minibooks &lt;a href=&#34;https://amzn.to/2Lm9gN9&#34;&gt;Ray Tracing: the Next Week&lt;/a&gt; and &lt;a href=&#34;https://amzn.to/2ySjG4n&#34;&gt;Ray Tracing: The Rest Of Your Life&lt;/a&gt;. You may find free editions of these books online but I am not completely sure they are approved by the author.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://amzn.to/2Wt4x2s&#34;&gt;Ray Tracing Gems&lt;/a&gt; - An excellent update to the previous set of books explaining the latest techniques focusing on real-time ray tracing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: References may contain affiliate links&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python - Show Notes of &#34;Ray Tracing a Coronavirus&#34;</title>
      <link>https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/</link>
      <pubDate>Fri, 10 Apr 2020 20:08:28 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/&#34;&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/&#34;&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/&#34;&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/&#34;&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/&#34;&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;The first ray-traced animation I had ever seen was in my first year of Engineering. My senior showed us a gold-plated logo of the institution slowly spinning and glinting in the light. It had an amazing level of detail - a triangular frame, a gear wheel on the left, a tower on the right and even a palm tree in the center. We were dying to know how he did it. When he showed us, it blew our minds - it was all &lt;a href=&#34;https://en.wikipedia.org/wiki/POV-Ray&#34;&gt;code&lt;/a&gt;! Every shape was made by combining (or subtracting) primitive solids like spheres, cylinders and cubes. It featured on the masthead of the first edition of our online magazine (distributed on ​3 1⁄2 inch floppies).&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;you can be more creative under constraints&#34;&gt;
&lt;/div&gt;
&lt;p&gt;Of course, these days 3D modelling is mostly done by artists in a graphics program like 3ds Max or Maya. But not everything is tinkered by the hand of an artist. Procedural code is still used to create thousands of unique soldiers in an army scene or an infinite world in a multiplayer game. Computer generated art can often surprise or amuse you.&lt;/p&gt;
&lt;p&gt;So when I had to design the model of the omnipresent SAR-Cov-2 virus for a poster, even though I was very tempted to use such tools, I opted to generate the model in code. My &lt;a href=&#34;https://github.com/arocks/puray&#34;&gt;Python raytracer&lt;/a&gt; (currently in it&amp;rsquo;s fourth part of the video series) was decent enough to create 3D looking spheres. Having only spheres is a big constraint but you can be more creative under constraints.&lt;/p&gt;
&lt;h2 id=&#34;deconstruction&#34;&gt;Deconstruction&lt;/h2&gt;
&lt;p&gt;There is a process fundamental to artistically recreating any real world object &amp;ndash; Deconstruction. When you learn to draw you are asked to &amp;ldquo;block out&amp;rdquo; the simple shapes you are trying to draw. So a face becomes an elongated sphere, a nose becomes a triangle etc. If your big shapes are correctly proportioned then it will be a lot easier to add in the details.&lt;/p&gt;
&lt;p&gt;In good old days, the computer artists used graph paper. Like my senior who traced the logo from the college magazine, enlarged it on graph paper and wrote down all the coordinates. These days you could use a 2D drawing program like Inkscape to overlay a photograph and trace over it. But the idea is essentially the same - find all the large blocking shapes that make your image.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://arunrocks.com/static/images/blog/prince-of-persia-graphpaper.jpg&#34; alt=&#34;Prince of Persia art&#34;  title=&#34;Graph paper sketch of Prince of Persia by Jordan Mechner in 1987&#34;  width=1080 height=&#34;786&#34;  /&gt;
    &lt;figcaption&gt;Graph paper sketch of Prince of Persia by Jordan Mechner in 1987&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;reconstruction&#34;&gt;Reconstruction&lt;/h2&gt;
&lt;p&gt;Generating the model in the computer can be a process of trial and error. In the days of slower computers, rendering a simple object took nearly an hour. Even with today&amp;rsquo;s dramatically faster machines, rendering a complex scene could take hours. There is simply a ton of numbers to crunch.&lt;/p&gt;
&lt;p&gt;In the case of the coronavirus, I needed to figure out how to make a crown. Essentially I needed to position points evenly around a circle. People say a lot of things about high school trigonometry and how much of a waste of time it was. But I found it quite useful not only to arrange the spikes of the crown but also give it a slight random shift. This would mean each time you render the virus would look sightly different. I had a lot of fun animating several renders to a beat in the video.&lt;/p&gt;
&lt;h2 id=&#34;presentation&#34;&gt;Presentation&lt;/h2&gt;
&lt;p&gt;I couldn&amp;rsquo;t stop playing with the model even after the poster was made. I tweaked it into various color combinations that I found online. Ironically, it looks distinctively charming in any avatar.&lt;/p&gt;
&lt;p&gt;It shows that simple things are awesome than the most professionally done creations. Especially if you could make your own. Looking forward to seeing what others would create with this.&lt;/p&gt;
&lt;p&gt;Here is the video:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/HH0rka1uF_g?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/arocks/puray/tree/episode04&#34;&gt;Code for part four&lt;/a&gt; is the starting point of the video.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/arocks/puray/tree/virusmodel&#34;&gt;Final code&lt;/a&gt; is also tagged in the repository.&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=KaCe63v4D_Q&amp;amp;list=PL8ENypDVcs3H-TxOXOzwDyCm5f2fGXlIS&#34;&gt;Puray Video Series playlist&lt;/a&gt; Watch the entire video tutorial to understand how this ray tracer was made from scratch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scripps.edu/news-and-events/press-room/2020/20200317-andersen-covid-19-coronavirus.html&#34;&gt;SARS-CoV-2 Electron Microsocope Image&lt;/a&gt; This article has the reference image I used.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python (Part 4) - Show Notes of &#34;Let there be light&#34;</title>
      <link>https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/</link>
      <pubDate>Sat, 28 Mar 2020 18:39:36 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/&#34;&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/&#34;&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/&#34;&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/&#34;&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/&#34;&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;Probably a &lt;a href=&#34;https://en.wikipedia.org/wiki/2019%E2%80%9320_coronavirus_pandemic&#34;&gt;global lockdown&lt;/a&gt; is a good time to resume a series that demands a lot of your time. Not really if your kids are home too. But I&amp;rsquo;ve been getting enough reminders through comments and emails that I thought it&amp;rsquo;s time to tackle this challenging episode.&lt;/p&gt;
&lt;p&gt;Yes, this is an episode with a lot of Physics and Mathematics. But you will observe it has a very gentle learning curve since there is enough background presented in the problem requirements and in previous episodes. The real challenge is in translating the math to code.&lt;/p&gt;
&lt;p&gt;Computers are computing devices crunching numbers all the time. So you might think implementing math formulas should be straightforward. Unless you are a scientist or a mathematician, in which case, you would know the truth which is &amp;ndash; it is not straightforward at all.&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;There are many ways you could get it wrong. But only one way to get it right.&#34;&gt;
&lt;/div&gt;
&lt;p&gt;I remember before Doom came out, it was very hard to develop a 3D engine. Most of the available research involved understanding computer graphics text books with a lot of math theory. It&amp;rsquo;s a painful task to translate formulas into algorithms and later performant code. There are many ways you could get it wrong. But only one way to get it right. Even more frustrating is forgetting to account for edge conditions like a negative result or divide by zero and floating point errors.&lt;/p&gt;
&lt;p&gt;I remember referring one of the most popular books at that time &lt;a href=&#34;https://amzn.to/33Wz5vM&#34;&gt;Numerical Recipes&lt;/a&gt; in C++ to understand how to implement some of the algorithms. But I had to abandon the project after a working prototype because making a game engine (alone) is a tonne of work!&lt;/p&gt;
&lt;p&gt;In this part, I have used a lot of images and slides to make sure that I don&amp;rsquo;t skip any explanations (like how cosine and dot products are related). I know that these videos are being watched by all kinds people &amp;ndash; students, experienced programmers and non-programmers. So I have not made any assumptions.&lt;/p&gt;
&lt;p&gt;Hopefully you would enjoy this part without any challenges. Even if you do, it should be fun 😊&lt;/p&gt;
&lt;p&gt;These are the topics we will cover in this episode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction
&lt;ul&gt;
&lt;li&gt;Adding lights&lt;/li&gt;
&lt;li&gt;Phong reflection model&lt;/li&gt;
&lt;li&gt;Ambient, Diffuse and Specular Shading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sub-problem: Let there be light&lt;/li&gt;
&lt;li&gt;Coding the solution
&lt;ul&gt;
&lt;li&gt;New classes&lt;/li&gt;
&lt;li&gt;Command-line arguments with argparse&lt;/li&gt;
&lt;li&gt;Progress Bar(?)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the video:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/fu_LuFU7iFo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Code for part four is tagged on the &lt;a href=&#34;https://github.com/arocks/puray/tree/episode04&#34;&gt;Puray Github project&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Books and articles that can help understand this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/33Xwh1h&#34;&gt;Game Engine Architecture&lt;/a&gt; Great introduction to graphics concepts and techniques used in computer games. It might be different from raytracing since focus is on realtime rendering rather than realism.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/howto/argparse.html&#34;&gt;Argparse Tutorial&lt;/a&gt; &lt;code&gt;argparse&lt;/code&gt; is the new standard for Python argument parsing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: References may contain affiliate links&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python (Part 3) - Show Notes of &#34;3D Balls in 2D Space&#34;</title>
      <link>https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/</link>
      <pubDate>Wed, 04 Dec 2019 22:19:43 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/&#34;&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/&#34;&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/&#34;&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/&#34;&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/&#34;&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;Graphics is what made Mathematics enjoyable for me. I first heard of trigonometric functions like sine and cosine when I read &lt;a href=&#34;https://en.wikipedia.org/wiki/IBM_BASIC#IBM_Advanced_BASIC&#34;&gt;GW-BASIC&lt;/a&gt; manual. Geometry was easy to visualize with the rudimentary graphics of LINE and CIRCLE statements. While I could see many struggle with Mathematics, I always found it interesting.&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;I needed to give personalities to the Ray and Sphere before I could show their intersection formula&#34;&gt;
&lt;/div&gt;
&lt;p&gt;So my challenge was to make this math-heavy episode interesting so that you see how I see it. I needed to give personalities to Ray and Sphere before I could show their intersection formula. This needed a lot of illustration and animation work. But I believe the end result was worth it.&lt;/p&gt;
&lt;p&gt;This time there is a lot of furious typing and less talking because of the number of lines entered in this part. I did not want to fast forward code writing segments because it doesn&amp;rsquo;t help the learners. In any case, YouTube can speed up videos if you choose to.&lt;/p&gt;
&lt;p&gt;These are the topics we will cover in this episode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction
&lt;ul&gt;
&lt;li&gt;Why meshes in movies and spheres in raytracers&lt;/li&gt;
&lt;li&gt;Simplified ray-tracing&lt;/li&gt;
&lt;li&gt;Ray-sphere intersection&lt;/li&gt;
&lt;li&gt;Aspect Ratio Corrections&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;First sub-problem: 3D Balls in 2D Space&lt;/li&gt;
&lt;li&gt;Coding the solution
&lt;ul&gt;
&lt;li&gt;Hex colors&lt;/li&gt;
&lt;li&gt;Classes for Engine, Ray, Sphere, etc.&lt;/li&gt;
&lt;li&gt;Rendering Algorithm&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the video:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/1DKlb3BQ_k8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Code for part three is tagged on the &lt;a href=&#34;https://github.com/arocks/puray/tree/episode03&#34;&gt;Puray Github project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bonus (Traffic Lights) Code is &lt;a href=&#34;https://www.toneden.io/ar-td/post/traffic-lights-bonus-content&#34;&gt;available for download&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Books and articles that can help understand this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2DKMISd&#34;&gt;Real-Time Collision Detection&lt;/a&gt; Great introduction and overview of different intersection and collision algorithms&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection&#34;&gt;Line–sphere intersection - Wikipedia&lt;/a&gt; Wikipedia page with the mathematical derivation of the formula we have used.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: References may contain affiliate links&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Tracer in Python (Part 2) - Show Notes of &#34;Revealing the True Colors&#34;</title>
      <link>https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/</link>
      <pubDate>Sun, 17 Nov 2019 12:41:50 +0530</pubDate>
      
      <guid>https://arunrocks.com/ray-tracer-in-python-2-revealing-the-true-colors/</guid>
      <description>

&lt;div class=&#34;series-box&#34;&gt;
  &lt;p&gt;You are reading a post from a multi-part series of articles&lt;/p&gt;
  &lt;ol&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-1-points-in-3d-space-show-notes/&#34;&gt;Ray Tracer in Python (Part 1) - Show Notes of &amp;#34;Points in 3D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;Ray Tracer in Python (Part 2) - Show Notes of &amp;#34;Revealing the True Colors&amp;#34;&lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-3-3d-balls-in-2d-space/&#34;&gt;Ray Tracer in Python (Part 3) - Show Notes of &amp;#34;3D Balls in 2D Space&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-4-let-there-be-light/&#34;&gt;Ray Tracer in Python (Part 4) - Show Notes of &amp;#34;Let there be light&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracing-a-coronavirus-in-puray-python/&#34;&gt;Ray Tracer in Python - Show Notes of &amp;#34;Ray Tracing a Coronavirus&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-5-light-reflections/&#34;&gt;Ray Tracer in Python (Part 5) - Show Notes of &amp;#34;Some Light Reflections&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    
    &lt;li&gt;
      &lt;a href=&#34;https://arunrocks.com/ray-tracer-in-python-part-6-of-firing-all-cores/&#34;&gt;Ray Tracer in Python (Part 6) - Show Notes of &amp;#34;Firing All Cores&amp;#34;&lt;/a&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

&lt;p&gt;It is always a good idea to create a visible output at the start of a long project. If you are making a game, start with showing something moving on the screen. It keeps you motivated and gives you something cool to show your friends as progress. In the second part of our ray tracer tutorial, I will introduce you to PPM a very simple image format that will be used for our renders. You don&amp;rsquo;t need to install any image libraries and yet PPM files can be read by most image viewers.&lt;/p&gt;
&lt;div data-pullquote=&#34;&amp;#34;Features like gamma correction and linear interpolation seemed like an overkill&#34;&gt;
&lt;/div&gt;
&lt;p&gt;The color class is a lot simpler than what I originally designed. Features like gamma correction and linear interpolation seemed like an overkill for a project like this. But I plan to add some convenience constructors later. Hopefully, this will be a good introduction to how colors are manipulated in computer graphics.&lt;/p&gt;
&lt;p&gt;These are the topics we will cover in this episode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction
&lt;ul&gt;
&lt;li&gt;Compressed Image are Hard&lt;/li&gt;
&lt;li&gt;What Images are Made of&lt;/li&gt;
&lt;li&gt;RGB triplets&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;First sub-problem: Revealing the True Colors&lt;/li&gt;
&lt;li&gt;Coding the solution
&lt;ul&gt;
&lt;li&gt;Use the shebang line&lt;/li&gt;
&lt;li&gt;Separate classes in separate files&lt;/li&gt;
&lt;li&gt;Why fileobj instead of filename?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the video:&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
			&lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/92tLWv_gajA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
		&lt;/div&gt;

&lt;p&gt;Code for part two is tagged on the &lt;a href=&#34;https://github.com/arocks/puray/tree/episode02&#34;&gt;Puray Github project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bonus (Gradient) Code is &lt;a href=&#34;https://www.toneden.io/ar-td/post/gradient-image-generator&#34;&gt;available for download&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;show-notes&#34;&gt;Show Notes&lt;/h3&gt;
&lt;p&gt;Books and articles that can help understand this part:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2WHBU06&#34;&gt;Understanding Compression by Colt McAnlis, Aleks Haecky&lt;/a&gt; A book covering image formats like JPG, PNG etc&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://pillow.readthedocs.io/en/stable/&#34;&gt;Python Imaging Library PIL or Pillow&lt;/a&gt; Popular Python library for reading and writing different image formats&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://amzn.to/2r9x28b&#34;&gt;A Field Guide to Digital Color by Maureen Stone&lt;/a&gt; Understand color theory beyond RGB triplets into vision and various color systems.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: References may contain affiliate links&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
