<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Vishnu's Tech Chronicle | Python Cipher Blog]]></title><description><![CDATA[Explore Python, tech trends, and development insights. Dive into a world of coding expertise and stay ahead in the ever-evolving tech landscape.]]></description><link>https://vishnutiwari.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1704136583394/8mefg1CjB.png</url><title>Vishnu&apos;s Tech Chronicle | Python Cipher Blog</title><link>https://vishnutiwari.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 17 Sep 2026 00:40:32 GMT</lastBuildDate><atom:link href="https://vishnutiwari.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Internal Mechanism of Iterator, Iterable, and Generator in Python]]></title><description><![CDATA[In the realm of Python programming, the concepts of iteration, iterables, and generators serve as fundamental pillars underlying the language's versatility and power. While often encountered in coding endeavors, these concepts can sometimes pose chal...]]></description><link>https://vishnutiwari.dev/internal-mechanism-of-iterator-iterable-and-generator-in-python</link><guid isPermaLink="true">https://vishnutiwari.dev/internal-mechanism-of-iterator-iterable-and-generator-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[iterator]]></category><category><![CDATA[iterable]]></category><category><![CDATA[generators]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Sun, 28 Apr 2024 12:15:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714306094331/b1d90a50-384f-46bc-b64a-246282dada44.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the realm of Python programming, the concepts of iteration, iterables, and generators serve as fundamental pillars underlying the language's versatility and power. While often encountered in coding endeavors, these concepts can sometimes pose challenges to grasp fully, particularly for those navigating their journey through Python's intricacies.</p>
<p>This article aims to demystify these fundamental constructs by delving into their internal mechanisms, offering clarity on their roles and importance within Python's ecosystem. By dissecting the nuances between iterators, iterables, and generators, readers will gain a profound understanding of how these elements shape the flow and efficiency of Python code.</p>
<p>Let's first look at what is Iterable?</p>
<h2 id="heading-iterable-in-python">Iterable - In Python</h2>
<p>An iterable means, as the name suggests, any object we can iterate over, but there's a little more we should know about this. Generally, we know what objects can be iterable. For example, a list or tuple can be iterated over through a loop. But how do we know what can be iterable or what can't? For this, we just need to check if the object has the <code>__iter__</code> method or not. Let me show you with an example.</p>
<p>Let's create a basic list in Python and iterate over it using a for loop. Also, we'll print all the properties and methods using the <code>dir()</code> method..</p>
<pre><code class="lang-python">my_list = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> my_list:
    print(i)

print(dir(i))
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong><em>dir()</em></strong>: This function will return all the properties and methods, even built-in properties which are default for all object</div>
</div>

<p><strong>Output</strong></p>
<pre><code class="lang-python"><span class="hljs-number">1</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
<span class="hljs-number">4</span>
[<span class="hljs-string">'__add__'</span>, <span class="hljs-string">'__class__'</span>, <span class="hljs-string">'__class_getitem__'</span>, <span class="hljs-string">'__contains__'</span>, <span class="hljs-string">'__delattr__'</span>, <span class="hljs-string">'__delitem__'</span>, <span class="hljs-string">'__dir__'</span>, <span class="hljs-string">'__doc__'</span>, <span class="hljs-string">'__eq__'</span>, <span class="hljs-string">'__format__'</span>, <span class="hljs-string">'__ge__'</span>, <span class="hljs-string">'__geta
ttribute__'</span>, <span class="hljs-string">'__getitem__'</span>, <span class="hljs-string">'__getstate__'</span>, <span class="hljs-string">'__gt__'</span>, <span class="hljs-string">'__hash__'</span>, <span class="hljs-string">'__iadd__'</span>, <span class="hljs-string">'__imul__'</span>, <span class="hljs-string">'__init__'</span>, <span class="hljs-string">'__init_subclass__'</span>, <span class="hljs-string">'__iter__'</span>, <span class="hljs-string">'__le__'</span>, <span class="hljs-string">'__len__'</span>,
 <span class="hljs-string">'__lt__'</span>, <span class="hljs-string">'__mul__'</span>, <span class="hljs-string">'__ne__'</span>, <span class="hljs-string">'__new__'</span>, <span class="hljs-string">'__reduce__'</span>, <span class="hljs-string">'__reduce_ex__'</span>, <span class="hljs-string">'__repr__'</span>, <span class="hljs-string">'__reversed__'</span>, <span class="hljs-string">'__rmul__'</span>, <span class="hljs-string">'__setattr__'</span>, <span class="hljs-string">'__setitem__'</span>, <span class="hljs-string">'__sizeof__
'</span>, <span class="hljs-string">'__str__'</span>, <span class="hljs-string">'__subclasshook__'</span>, <span class="hljs-string">'append'</span>, <span class="hljs-string">'clear'</span>, <span class="hljs-string">'copy'</span>, <span class="hljs-string">'count'</span>, <span class="hljs-string">'extend'</span>, <span class="hljs-string">'index'</span>, <span class="hljs-string">'insert'</span>, <span class="hljs-string">'pop'</span>, <span class="hljs-string">'remove'</span>, <span class="hljs-string">'reverse'</span>, <span class="hljs-string">'sort'</span>]

[Process exited <span class="hljs-number">0</span>]
</code></pre>
<p>So, if you see the output and find a dunder method called <code>__iter__</code>, it means we can iterate over it; otherwise, no.</p>
<p>Now I guess, we are pretty much clear about iterables, Now let's move to Iterators.</p>
<h2 id="heading-iterator-in-python">Iterator - In Python</h2>
<p>An iterator in Python is indeed iterable; it can be looped over, and it includes the dunder method <code>__iter__</code> in its default properties. However, what sets an iterator apart from an iterable?</p>
<p>An iterator is an object with a state, allowing it to remember its position during iteration. While this terminology might seem dense, it becomes clearer with examples. Iterators have a state, enabling them to determine where they are in the iteration process. Moreover, iterators know how to retrieve their next value, accomplished through a dunder method called <code>next</code>.</p>
<p>Let's revisit our previous output. We observe that a list lacks a <code>next</code> method, and it also lacks any state information. Consequently, a list does not possess knowledge of its state or how to retrieve its next value, rendering it not an iterator.<br />Now, how can we create our iterator so that it can retain its state and retrieve the next value?</p>
<p><strong>We achieve this by invoking the dunder method</strong> <code>iter</code> <strong>on our iterable, thereby transforming it into an iterator.</strong></p>
<pre><code class="lang-python">new = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]

i_new = iter(new) 
<span class="hljs-comment"># OR</span>
i_new = new.__iter__()

print(i_new)
print(dir(i_new))
</code></pre>
<p><strong>Output</strong></p>
<pre><code class="lang-python">&lt;list_iterator object at <span class="hljs-number">0x100fc1c60</span>&gt;
[<span class="hljs-string">'__class__'</span>, <span class="hljs-string">'__delattr__'</span>, <span class="hljs-string">'__dir__'</span>, <span class="hljs-string">'__doc__'</span>, <span class="hljs-string">'__eq__'</span>, <span class="hljs-string">'__format__'</span>, <span class="hljs-string">'__ge__'</span>, <span class="hljs-string">'__getattribute__'</span>, <span class="hljs-string">'__getstate__'</span>, <span class="hljs-string">'__gt__'</span>, <span class="hljs-string">'__hash__'</span>, <span class="hljs-string">'__init__'</span>, <span class="hljs-string">'__init_subcla
ss__'</span>, <span class="hljs-string">'__iter__'</span>, <span class="hljs-string">'__le__'</span>, <span class="hljs-string">'__length_hint__'</span>, <span class="hljs-string">'__lt__'</span>, <span class="hljs-string">'__ne__'</span>, <span class="hljs-string">'__new__'</span>, <span class="hljs-string">'__next__'</span>, <span class="hljs-string">'__reduce__'</span>, <span class="hljs-string">'__reduce_ex__'</span>, <span class="hljs-string">'__repr__'</span>, <span class="hljs-string">'__setattr__'</span>, <span class="hljs-string">'__setstate__'</span>, <span class="hljs-string">'__s
izeof__'</span>, <span class="hljs-string">'__str__'</span>, <span class="hljs-string">'__subclasshook__'</span>]

[Process exited <span class="hljs-number">0</span>]
</code></pre>
<p>Now, observing the properties, we notice the presence of both the dunder methods <code>iter</code> and <code>next</code>, confirming that it is indeed an iterator object. However, you may wonder why the iterator itself has an <code>iter</code> method, reminiscent of the case with a list. This occurrence arises because an iterator is also iterable. Therefore, running <code>iter</code> on an iterator simply returns the same object.</p>
<p>Let's delve into the <code>next</code> method with an example.</p>
<pre><code class="lang-python">new = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]

i_new = iter(new)

print(i_new)

print(next(i_new))
print(next(i_new))
print(next(i_new))
print(next(i_new))
print(next(i_new))
</code></pre>
<p><strong>Output</strong></p>
<pre><code class="lang-python">&lt;list_iterator object at <span class="hljs-number">0x1045b7fd0</span>&gt;
<span class="hljs-number">1</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
<span class="hljs-number">4</span>
Traceback (most recent call last):
  File <span class="hljs-string">"/Users/vishnu.tiwari/Desktop/Python/Misc/iig.py"</span>, line <span class="hljs-number">11</span>, <span class="hljs-keyword">in</span> &lt;module&gt;
    print(next(i_new))
          ^^^^^^^^^^^
StopIteration

[Process exited <span class="hljs-number">1</span>]
</code></pre>
<p>As mentioned, an iterator retains its state throughout the iteration process and knows its next value. In the previous example, every time we request the next value from our iterator object, it recalls its previous state and provides the subsequent value. Once it exhausts all available values, it raises the <code>StopIteration</code> exception. This exception indicates that the iterator has been depleted and has no more values to offer.</p>
<p>Now let's talk about the diamond topic which you won't find more articles about it which is the mechanism of a for loop in Python</p>
<hr />
<h3 id="heading-mechanism-of-foor-loop-python">Mechanism Of Foor Loop - Python</h3>
<p>When we run a normal for loop, it knows how to handle the stop iteration exception and it doesn't show it to us. In the background a for loop is doing something like this, it's first getting an iterator of our original object and then it's getting the next values. until it hits a stop iteration exception.</p>
<p>Under the hood for loop itself uses a while loop and work like this.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Normal For Loop </span>
<span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> iterable:
    <span class="hljs-comment"># do something with item</span>
    <span class="hljs-keyword">pass</span>
</code></pre>
<p>BTS</p>
<pre><code class="lang-python">iterator = iter(iterable)
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    <span class="hljs-keyword">try</span>:
        item = next(iterator)
    <span class="hljs-keyword">except</span> StopIteration:
        <span class="hljs-keyword">break</span>
    <span class="hljs-comment"># do something with item</span>
</code></pre>
<hr />
<details><summary>Forward</summary><div data-type="detailsContent">An Iterator can only go forward, it can't go backward.</div></details>

<h2 id="heading-generator">Generator</h2>
<p>Some of you may have used generators, they're extremely useful for creating easy to read iterator, they look a lot like normal functions but instead of retuning a result, they instead yield a value and when they yield a value it keeps that state until the generator is run again and yields the next value so generator are iterators as well but the dunder iter and next methods are created automatically.</p>
<p>When a function contains one or more <code>yield</code> statements, Python treats it as a generator function. When you call a generator function, it returns a generator object without executing the function's code immediately. Instead, the function's code runs in response to the iterator's <code>__next__()</code> method being called.</p>
<p>Here's a simplified explanation of how a generator function works under the hood:</p>
<ul>
<li><p>When you call a generator function, it returns a generator object.</p>
</li>
<li><p>Each time you call the generator object's <code>__next__()</code> method (implicitly via a loop or explicitly), the generator function executes until it encounters a <code>yield</code> statement.</p>
</li>
<li><p>When a <code>yield</code> statement is reached, the value specified with <code>yield</code> is returned, and the function's execution is paused. The generator object retains its state, including the local variables' values.</p>
</li>
<li><p>When the generator object's <code>__next__()</code> method is called again, execution resumes from where it left off, continuing until the next <code>yield</code> statement or the end of the function is reached.</p>
</li>
<li><p>When there are no more <code>yield</code> statements in the function or a <code>return</code> statement is encountered, a <code>StopIteration</code> exception is raised, indicating that the generator has exhausted its sequence.</p>
</li>
</ul>
<p>Here's a conceptual example to illustrate how this works:</p>
<pre><code class="lang-python">pythonCopy codedef my_generator():
    print(<span class="hljs-string">"Start of generator"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">1</span>
    print(<span class="hljs-string">"After first yield"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">2</span>
    print(<span class="hljs-string">"After second yield"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">3</span>
    print(<span class="hljs-string">"End of generator"</span>)

gen = my_generator()  <span class="hljs-comment"># Create a generator object</span>
print(next(gen))  <span class="hljs-comment"># Output: 1</span>
print(next(gen))  <span class="hljs-comment"># Output: 2</span>
print(next(gen))  <span class="hljs-comment"># Output: 3</span>
<span class="hljs-comment"># print(next(gen))  # Raises StopIteration error</span>
</code></pre>
<p>In this example, you can see how the generator function's code is executed up to the first <code>yield</code> statement when <code>next(gen)</code> is called for the first time. The function's execution is paused, and the value <code>1</code> is returned. Subsequent calls to <code>next(gen)</code> resume the function's execution from where it last yielded.</p>
<h2 id="heading-summary">Summary</h2>
<p>This article delves into the fundamental concepts of iteration, iterables, iterators, and generators in Python. It explains the differences between them, how to identify iterables, create iterators, and utilize generators. Additionally, it explores the mechanism of a for loop and provides insights into the workings of generators through examples.</p>
]]></content:encoded></item><item><title><![CDATA[How Python Really Works | In-Depth Analysis | Python 3.# | Internal Mechanism |]]></title><description><![CDATA[In this article, I'll delve into how Python truly operates. I will try to cover every functional aspect, from writing a code to executing it. This article is basically for intermediate Python users with a knowledge of basic and intermediate programmi...]]></description><link>https://vishnutiwari.dev/how-python-really-works-in-depth-analysis-python-3-internal-mechanism</link><guid isPermaLink="true">https://vishnutiwari.dev/how-python-really-works-in-depth-analysis-python-3-internal-mechanism</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[python projects]]></category><category><![CDATA[Django]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Thu, 15 Feb 2024 14:36:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708007368308/e28b4a04-8a83-49f6-a4b7-160cb908a859.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I'll delve into how Python truly operates. I will try to cover every functional aspect, from writing a code to executing it. This article is basically for intermediate Python users with a knowledge of basic and intermediate programming concepts, algorithms, and more. Let's begin with the idea behind Python's creation!</p>
<p>Python is <strong><em>a popular programming language</em></strong>. It was created by Guido van Rossum, and released in 1991.....Hey F#ck Stop it!...</p>
<p><img src="https://lh3.googleusercontent.com/proxy/4WXnscn0qgGCeit53wZSeInWze_uqYgxAqqTpU5VJh2bgvG9XWBaCzcE6JxghhDoTZgCOpenCamtC_b8-CopoG3ycOToKGQxqH3nWExgZ_UJTA" alt class="image--center mx-auto" /></p>
<p>I know you are annoyed with this wikipedia shit, but trust me, things will make sense if you know why python was created.</p>
<h2 id="heading-chapter-1-born-of-a-warrior-python">Chapter 1 : Born of a warrior (Python)</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707988480919/3ccf228c-99ed-4b6e-b6ec-1d76a575d6e9.png" alt class="image--center mx-auto" /></p>
<p>The common programming languages between 1980 to 1990 were C, Pascal, Fortran, COBOL, BASIC, etc. During that time, the computer industry was growing rapidly. Many intelligent individuals understood the future potential of computers and recognised that softwares will play a crucial role in making them more intriguing. Consequently, some people changed their careers from different domains to software development. Most of them have a innovative ideas, but to implement their own idea, they first needed to learn a programming language, which was a complex task.</p>
<p>During that era, developers had to handle everything by themselves, from managing memory to dealing with common tasks like buffer overflow, memory leaks which were both commonplace and repetitive.</p>
<h3 id="heading-guido-van-rossum-joined-the-chat">Guido van Rossum joined the chat...</h3>
<p>During that era, Guido van Rossum was working at the Centrum Wiskunde &amp; Informatica (CWI) in the Netherlands, a national research institute for mathematics and computer science.</p>
<p>Guido had been involved in various projects related to distributed systems and operating systems at CWI, and has gained valuable experience in software development.</p>
<p>During his time at CWI, Guido was dissatisfied with the existing programming languages available, finding them either too complex or lacking in certain areas. He had experience with languages like ABC and Modula-3, which influenced his thinking about language design.</p>
<p>Motivated by a desire to create a programming language that emphasized simplicity, readability, and productivity, Guido started working on a personal project to develop what would become Python. Drawing inspiration from his experiences with other languages and his desire to address their limitations, Guido set out to design a language that would be easy to learn and use, yet powerful enough to tackle a wide range of tasks.</p>
<p>Python was initially developed as a hobby project by Guido during his spare time at CWI. He worked on refining the language's syntax and semantics, carefully crafting features that would make it intuitive and expressive. Guido's goal was to create a language that would enable programmers to write clear, concise code that could be easily understood and maintained, without sacrificing flexibility or power.</p>
<p>As Python gained popularity within CWI and beyond, Guido decided to dedicate more time to its development, eventually leaving his job at CWI to focus on Python full-time.</p>
<h3 id="heading-becoming-a-bad-boy">Becoming a Bad Boy</h3>
<p>After gaining popularity python started to roast their other friends like C, COBOL, FORTAN. it's not my words, he actually started bullying every programming language. Here are some of the examples.</p>
<p><strong>C</strong>: Ah, C, the powerhouse of the era, loved for its speed and low-level control. But let's face it, memory management in you was like walking through a minefield. I (Python) comes in like a superhero with my automatic memory management, sparing developers from the headache of manual memory allocation and pesky segmentation faults.</p>
<p><strong>Pascal</strong>: Bless Pascal's heart for its structured programming and strong typing, but its verbosity could put anyone to sleep. Python swoops in with its clean and concise syntax, making code elegant and readable without sacrificing functionality.</p>
<p><strong>Fortran</strong>: Sure, Fortran was the go-to for numerical computing, but its syntax felt like a blast from the past even back then. Python's modern and flexible syntax feels like a breath of fresh air, attracting scientists and engineers with its ease of use and extensive libraries for numerical computing.</p>
<p>Since he become a bad boy, people started hating him for everything from being slow asf to being rude.</p>
<p>C(Queen) said : "<em>what's with your performance? Sure, you're great for scripting and prototyping, but when it comes to heavy lifting, you're about as fast as a sloth on tranquilizers. Don't even get me started on your GIL (Global Interpreter Lock). Multithreading? More like multi-slowing.</em>"</p>
<p>Am just joking, please don't search for facts.. It is my made up controversy. But python being slow is really a thing 😂.</p>
<h2 id="heading-chapter-2-python-being-python-memory-genius">Chapter 2: Python Being Python (Memory Genius)</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707998411634/16e5a307-2f81-4468-b558-611f38024e6c.png" alt class="image--center mx-auto" /></p>
<p>Let's now get into the serious stuff. For understanding how python works, we need to understand first , how python memory is managed because it directly impacts the performance and behaviour of Python programs.</p>
<p>Memory management in Python differs from languages like C or C++, where developers have explicit control over memory allocation and deallocation.</p>
<p>In Python, memory management is handled by the Python runtime using a combination of techniques such as automatic memory allocation, garbage collection, and reference counting.</p>
<p>Now let's <strong>start</strong> understanding</p>
<ul>
<li><p>Whenever a program or file is created and if you are using it! It takes a significant amount of memory in your RAM. Same goes for a python program in execution mode, that also takes some amount of memory in the RAM.</p>
</li>
<li><p>The memory which is allocated to the python program in ram is further divided into two regions.</p>
</li>
<li><p><strong>Stack and Private Heap Space</strong></p>
</li>
<li><p>Object always gets created in Heap Space and the variable name gets allocated in stack.</p>
</li>
<li><p>Let me explain you with an example. Suppose there is a file name called test.py which contains:</p>
</li>
<li><pre><code class="lang-python">      a = <span class="hljs-number">10</span>
</code></pre>
</li>
<li><p>Now <code>10</code> is a int object and The variable <code>a</code> is created as a reference to this integer object. Now where the object 10 will be created? in the RAM, but where in RAM? the region allocated to the program in RAM? but which region? The <strong>Answer</strong> is <code>PRIVATE HEAP SPACE.</code><br />  Each object also gonna have an address in the heap space.<br />  - Where does the name gets created?<br />  The name <code>a</code> gonna create in <code>STACK</code> and a has the address of its object. which means a is gonna point to the address of 10.</p>
<p>  And python automatically checks the type of your object, that's why it is a dynamically typed language.</p>
</li>
<li><p>I created a diagram for better understanding.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707996946124/ed6123c4-0b8b-4289-80fd-c9a776b414b5.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<h3 id="heading-take-out-the-trash-garbage-collector">Take out the trash : Garbage Collector</h3>
<p>In Python, the garbage collector is responsible for reclaiming memory occupied by objects that are no longer in use, thus freeing up resources and preventing memory leaks. Python's garbage collector uses a technique called reference counting along with cyclic garbage collection to manage memory.</p>
<p><strong>You won't understand like this let me tell you a story</strong></p>
<p>Imagine Python's garbage collector as a diligent janitor named Gary. His job is to keep Python's memory clean and tidy, ensuring there's no garbage lying around.</p>
<p>Now, Gary's first tool in his arsenal is "reference counting." It's like keeping track of how many times someone mentions a particular item. So, whenever someone (or some variable) mentions an object, Gary scribbles a tally mark on his clipboard. When nobody mentions the object anymore, Gary checks his clipboard. If the tally reaches zero, he knows it's safe to throw that object into the garbage bin.</p>
<p>But wait, sometimes things get a bit tricky. Picture two objects, let's call them Bert and Ernie, holding hands in a circle and giggling like schoolkids. They're referencing each other, creating a loop that Gary's reference counting can't handle. It's like Bert says, "I'm holding Ernie's hand," and Ernie says, "I'm holding Bert's hand," and they just go around in circles forever.</p>
<p>Now, Gary scratches his head. He can't just rely on his tally marks to clean up this mess. So, he brings out his special tool: the "cyclic garbage collector." It's like a magical broom that can sweep away those circular references. With a flick of his wrist, Gary breaks the loop, and Bert and Ernie can finally let go of each other's hands and go their separate ways.</p>
<p>And that, my friend, is how Python's garbage collector, with the help of Gary the janitor, keeps Python's memory squeaky clean, one object at a time. Just don't let him catch you leaving your variables lying around unattended!Imagine Python's garbage collector as a diligent janitor named Gary. His job is to keep Python's memory clean and tidy, ensuring there's no garbage lying around.</p>
<p>Now, Gary's first tool in his arsenal is "reference counting." It's like keeping track of how many times someone mentions a particular item. So, whenever someone (or some variable) mentions an object, Gary scribbles a tally mark on his clipboard. When nobody mentions the object anymore, Gary checks his clipboard. If the tally reaches zero, he knows it's safe to throw that object into the garbage bin.</p>
<p>But wait, sometimes things get a bit tricky. Picture two objects, let's call them Bert and Ernie, holding hands in a circle and giggling like schoolkids. They're referencing each other, creating a loop that Gary's reference counting can't handle. It's like Bert says, "I'm holding Ernie's hand," and Ernie says, "I'm holding Bert's hand," and they just go around in circles forever.</p>
<p>Now, Gary scratches his head. He can't just rely on his tally marks to clean up this mess. So, he brings out his special tool: the "cyclic garbage collector." It's like a magical broom that can sweep away those circular references. With a flick of his wrist, Gary breaks the loop, and Bert and Ernie can finally let go of each other's hands and go their separate ways.</p>
<p>And that, my friend, is how Python's garbage collector, with the help of Gary the janitor, keeps Python's memory squeaky clean, one object at a time. Just don't let him catch you leaving your variables lying around unattended!</p>
<h2 id="heading-chapter-3-the-matrix-python">Chapter 3: The Matrix | Python</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1707999272265/a4c789d0-cf20-4319-9c44-4977f94e865d.png" alt class="image--center mx-auto" /></p>
<p>In "The Matrix," the protagonist Neo discovers that the world he perceives as reality is actually a simulated environment created by sentient machines. Similarly, in the world of Python programming, developers often work with abstracted concepts and tools that may seem straightforward on the surface but actually operate in a more complex manner behind the scenes.</p>
<p>In "The Matrix," the simulated reality is controlled and manipulated by the sentient machines, who use it to subdue and control humanity. Similarly, the Python interpreter serves as the gatekeeper to the simulated reality of Python code, interpreting and executing instructions according to its programming.</p>
<p><strong>But How Does Python Interpreter Really Works?</strong></p>
<h3 id="heading-first-step-lexical-analysis-and-parsing">First Step: Lexical Analysis and Parsing</h3>
<p>When you make a script or add lines of code and execute the program. Python Interpreter reads the code line by line, just like the execution flow. However, there are some exceptions to this rule. For example, if a line of code contains a loop, function call, or other control flow structure, the interpreter may need to execute multiple lines of code before moving on to the next line.</p>
<p><strong>Lexical Analysis</strong>: When you execute the python code. The first step is lexical analysis, also known as tokenization. During this process, the Python interpreter breaks the code into individual tokens such as keywords, identifiers, operators, and literals. These tokens form the basic building blocks of the Python language.</p>
<p><strong>Parsing</strong> : Once the code has been tokenized, the Python interpreter parses it to create an abstract syntax tree (<strong>AST</strong>). The AST represents the hierarchical structure of the code, with nodes corresponding to different elements such as expressions, statements, and functions. The parser ensures that the code follows the syntactic rules of the Python language.</p>
<h3 id="heading-second-step-bytecode-generation">Second Step: ByteCode Generation</h3>
<p>After parsing, the Python interpreter generates <strong>bytecode</strong> instructions based on the AST. Bytecode is a low-level, platform-independent representation of the Python code that the PVM(Python Virtual Machine) can execute. Each bytecode instruction corresponds to a specific operation or action, such as loading a value onto the stack, calling a function, or performing arithmetic operations.</p>
<p>In Python, the bytecode is stored in a <code>.pyc</code> file. In Python 3, the bytecode files are stored in a folder named <code>__pycache__</code>. This folder is automatically created when you try to import another file that you created:</p>
<h3 id="heading-third-step-bytecode-execution">Third Step: ByteCode Execution</h3>
<p>The bytecode generated by the Python interpreter is executed by the Python Virtual Machine (PVM). The PVM is responsible for interpreting and executing the bytecode instructions generated from the Python source code. It provides a runtime environment that manages memory, handles exceptions, and interacts with the underlying operating system to execute Python programs.</p>
<p>In summary, the Python interpreter compiles Python source code into bytecode, and the Python Virtual Machine executes this bytecode to run the Python program. This separation of concerns between compilation and execution allows Python code to be platform-independent and easily portable across different operating systems and hardware architectures.</p>
<p>I made a diagram for better understanding.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708002533799/6b450f52-0365-462d-8b5b-dada21262dd7.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-example-a-python-code-working">Example : A python code working</h3>
<p>Let's walk through the full working of a Python code example:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Define a function to calculate the factorial of a number</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">factorial</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n == <span class="hljs-number">0</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> n * factorial(n - <span class="hljs-number">1</span>)

<span class="hljs-comment"># Main program</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    <span class="hljs-comment"># Prompt the user for input</span>
    num = int(input(<span class="hljs-string">"Enter a number: "</span>))

    <span class="hljs-comment"># Calculate and display the factorial of the input number</span>
    print(<span class="hljs-string">"Factorial of"</span>, num, <span class="hljs-string">"is"</span>, factorial(num))
</code></pre>
<p>Now, let's break down the execution of this code step by step:</p>
<ol>
<li><p>The Python interpreter reads the source code file line by line.</p>
</li>
<li><p>The interpreter encounters the <code>def</code> keyword, indicating the definition of a function named <code>factorial</code>. The function definition is stored in memory for later use.</p>
</li>
<li><p>The interpreter moves to the <code>if __name__ == "__main__":</code> block, which checks if the script is being run as the main program.</p>
</li>
<li><p>Since the script is indeed being run as the main program, the interpreter proceeds to execute the code inside the <code>if</code> block.</p>
</li>
<li><p>The <code>input()</code> function prompts the user to enter a number, which is then converted to an integer using <code>int()</code> and assigned to the variable <code>num</code>.</p>
</li>
<li><p>The <code>factorial()</code> function is called with the input number as an argument. This triggers a recursive chain of function calls to calculate the factorial of the input number.</p>
</li>
<li><p>Each recursive call to <code>factorial()</code> decrements the input number by 1 until it reaches 0, at which point the base case (<code>if n == 0:</code>) is triggered, and the function returns 1.</p>
</li>
<li><p>As the recursive calls unwind, each intermediate result is multiplied by the current number until the final factorial value is computed.</p>
</li>
<li><p>The calculated factorial value is then printed to the console using <code>print()</code>.</p>
</li>
<li><p>The program execution finishes, and the Python interpreter exits.</p>
</li>
</ol>
<p>During this process, the Python interpreter compiles the source code into bytecode, which is then executed by the Python Virtual Machine (PVM). The PVM manages memory, handles function calls, and performs other runtime tasks to execute the Python program efficiently.</p>
<h2 id="heading-chapter-3-a-slow-end">Chapter 3: A Slow End</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708004807534/3653693a-4bfd-47e7-8002-53b6885e8056.png" alt class="image--center mx-auto" /></p>
<p>While Python has earned widespread acclaim for its simplicity, readability, and versatility, one criticism that often arises is its perceived lack of speed compared to lower-level languages like C or C++. In this chapter, we'll explore why Python may be slower in certain contexts and how developers can mitigate performance concerns. Let's dive in!</p>
<p>Understanding Python's Execution Model</p>
<p>Python's dynamic typing, automatic memory management, and high-level abstractions contribute to its ease of use and rapid development cycle. However, these features can also introduce overhead that impacts performance.</p>
<p>One factor that contributes to Python's runtime overhead is its interpreted nature. Unlike compiled languages, where code is translated directly into machine code before execution, Python code is first compiled into bytecode and then interpreted by the Python Virtual Machine (PVM). While this approach offers flexibility and platform independence, it can result in slower execution speeds compared to compiled languages.</p>
<p>Additionally, Python's Global Interpreter Lock (GIL) poses a limitation on multi-threaded performance. The GIL ensures that only one thread executes Python bytecode at a time, effectively preventing multi-core parallelism in CPU-bound tasks. While this simplifies memory management and concurrency control, it can lead to suboptimal performance in multi-threaded applications.</p>
<p>Example: Comparing Python and C in Matrix Multiplication</p>
<p>To illustrate the performance difference between Python and a compiled language like C, let's consider a simple example of matrix multiplication implemented in both languages.</p>
<p>Python Implementation:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-comment"># Generate random matrices</span>
size = <span class="hljs-number">1000</span>
matrix_a = np.random.rand(size, size)
matrix_b = np.random.rand(size, size)

<span class="hljs-comment"># Perform matrix multiplication</span>
result = np.dot(matrix_a, matrix_b)
</code></pre>
<p>C Implementation:</p>
<pre><code class="lang-c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span>

<span class="hljs-meta">#<span class="hljs-meta-keyword">define</span> SIZE 1000</span>

<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">matrix_multiply</span><span class="hljs-params">(<span class="hljs-keyword">double</span> matrix_a[SIZE][SIZE], <span class="hljs-keyword">double</span> matrix_b[SIZE][SIZE], <span class="hljs-keyword">double</span> result[SIZE][SIZE])</span> </span>{
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; SIZE; i++) {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; SIZE; j++) {
            result[i][j] = <span class="hljs-number">0</span>;
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> k = <span class="hljs-number">0</span>; k &lt; SIZE; k++) {
                result[i][j] += matrix_a[i][k] * matrix_b[k][j];
            }
        }
    }
}

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">double</span> matrix_a[SIZE][SIZE];
    <span class="hljs-keyword">double</span> matrix_b[SIZE][SIZE];
    <span class="hljs-keyword">double</span> result[SIZE][SIZE];

    <span class="hljs-comment">// Initialize matrices with random values</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; SIZE; i++) {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; SIZE; j++) {
            matrix_a[i][j] = (<span class="hljs-keyword">double</span>) rand() / RAND_MAX;
            matrix_b[i][j] = (<span class="hljs-keyword">double</span>) rand() / RAND_MAX;
        }
    }

    <span class="hljs-comment">// Perform matrix multiplication</span>
    matrix_multiply(matrix_a, matrix_b, result);

    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
<p>In this example, we generate two random matrices of size 1000x1000 and multiply them using both Python's NumPy library (which is implemented in C) and a C program. We then compare the execution times of both implementations.</p>
<p>Conclusion and Mitigation Strategies</p>
<p>While Python may not always match the raw speed of compiled languages like C, there are several strategies developers can employ to improve performance:</p>
<ul>
<li><p>Utilize libraries and extensions: Python offers extensive libraries and extensions, such as NumPy, Cython, and Numba, which provide optimized implementations for numerical and computationally intensive tasks.</p>
</li>
<li><p>Profile and optimize critical code paths: Identify performance bottlenecks using profiling tools like cProfile or line_profiler, and optimize critical code paths using techniques such as algorithmic improvements, caching, or parallelization.</p>
</li>
<li><p>Offload performance-critical tasks to compiled languages: Use tools like ctypes or Cython to interface with C/C++ code for performance-critical tasks while maintaining the high-level expressiveness of Python.</p>
</li>
</ul>
<p>By understanding Python's execution model and employing optimization techniques, developers can strike a balance between productivity and performance, ensuring that Python remains a powerful tool for a wide range of applications.</p>
<p>With this chapter, we've explored the nuances of Python's performance characteristics and provided insights into mitigating performance concerns. Armed with this knowledge, developers can harness the full potential of Python while addressing performance requirements in their projects.</p>
<p><img src="https://t4.ftcdn.net/jpg/04/32/24/55/360_F_432245541_vF5oiMc7MsUwxXdsOksaky6pGMVB8qyu.jpg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[How To Check The Performance Of Your Code in Python | Ft Timeit and cProfile module]]></title><description><![CDATA[Whenever we write code for a product, project, or any service we are working on, the next step before committing or pushing changes in the Version Control System (VCS) is to check the performance, often referred to as benchmarking. It is a crucial pa...]]></description><link>https://vishnutiwari.dev/how-to-check-the-performance-of-your-code-in-python-ft-timeit-and-cprofile-module</link><guid isPermaLink="true">https://vishnutiwari.dev/how-to-check-the-performance-of-your-code-in-python-ft-timeit-and-cprofile-module</guid><category><![CDATA[timeit]]></category><category><![CDATA[cprofile]]></category><category><![CDATA[python optimization]]></category><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[python libraries]]></category><category><![CDATA[modules]]></category><category><![CDATA[performance]]></category><category><![CDATA[Performance Optimization]]></category><category><![CDATA[optimization]]></category><category><![CDATA[python projects]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Thu, 25 Jan 2024 13:42:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707140872880/2bdd3a04-e98b-4d6c-8445-fa50afdf2e87.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Whenever we write code for a product, project, or any service we are working on, the next step before committing or pushing changes in the Version Control System (VCS) is to check the performance, often referred to as benchmarking. It is a crucial part of code optimization.</p>
<p><img src="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F885eb7eb-ec11-47cf-92af-99a557041370_498x373.gif" alt="The Patron Saint of Salad Dressing - by Annie Bethancourt" class="image--center mx-auto" /></p>
<h2 id="heading-why-it-is-crucial">Why it is crucial?</h2>
<p>Just imagine working on a feature for a product that is expected to be used by 3000-4000 users. For example, you write one piece of code that takes 15 seconds to complete a certain task. Afterward, you optimize the code, and now it performs the same task in 10 seconds. Initially, you might think it's just a 5-second difference, not much. However, if you calculate the impact, considering one user visiting that feature three times a day, resulting in 15 seconds saved daily, 7.5 minutes saved monthly, and 1.5 hours saved annually. If the product is used by 4000 users, this amounts to 6000 hours saved.</p>
<p>This means even a small improvement in your code could save a considerable amount of time for the customer. In the modern world, we all know that time is equivalent to real money.</p>
<p>But optimizing the code is boring asf!!!!</p>
<p><img src="https://i.pinimg.com/originals/7d/1f/2f/7d1f2f615788ee1b35ef65d4107d8036.gif" alt class="image--center mx-auto" /></p>
<p>I know it looks boring but trust me, it won't be boring if you play it like a game. Think of each optimization as leveling up in your coding adventure. 🚀💻</p>
<p>Some intellectual says we are also saving energy by optimizing the code as optimized code requires fewer resources since it also contributes to energy efficiency. It aligns with the trend towards more sustainable computing practices.</p>
<p>Having grasped the significance of code performance and profiling, let's delve into the methods for measuring how well our code performs.</p>
<h2 id="heading-timeit-module-for-small-snippets-of-code">timeit Module - for small snippets of code</h2>
<ul>
<li><p><strong>Purpose:</strong><code>timeit</code> is designed for measuring the execution time of small code snippets or functions.</p>
</li>
<li><p><strong>Usage:</strong> It's suitable for quick and simple measurements to get an idea of how long it takes to run a specific piece of code.</p>
</li>
</ul>
<p>The <code>timeit</code> module in Python provides a simple way to measure the execution time of small bits of Python code. It is particularly useful for assessing the performance of specific code snippets or functions. The <code>timeit</code> module can be employed both in the command line and within scripts to obtain accurate timing information. It helps in evaluating the efficiency of different implementations and aids in making informed decisions regarding code optimization.</p>
<p>And I just want to stress that <code>timeit</code> should be used strictly for small snippets of code.</p>
<p><code>timeit</code> runs the code multiple times and calculates the average time taken. This helps in getting more reliable and repeatable results, especially for short-running code where the timing might be affected by other processes running on the system.</p>
<p>Let's see how we can use timeit to check the code performance.<br />Here am importing three modules</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> timeit <span class="hljs-comment"># timeit module</span>
<span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> random
</code></pre>
<p>I imported 3 modules, now let's take a simple example and check which is the fastest from two inbuilt random function</p>
<ol>
<li><p><code>random.randint(a, b)</code>:</p>
<p> This function is used to generate a random integer between the specified range <code>[a, b]</code>.</p>
</li>
<li><p><code>random.random()</code>:</p>
<p> It gives a random float between 0 and 1</p>
</li>
</ol>
<p>Let's test which one is fast between these two.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> timeit
<span class="hljs-keyword">import</span> random
<span class="hljs-keyword">import</span> time

<span class="hljs-string">"""
There are two inbuilt function in random which is 
1. random.randint
2. random.random

1. it gives the random number between two numbers which user provides.
2. it gives random float between 0 and 1.
"""</span>

print(random.randint(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>))
print(random.random())


randint_checker = timeit.timeit(stmt=<span class="hljs-string">'random.randint(0,5)'</span>,
                                setup=<span class="hljs-string">'import random'</span>,
                                number=<span class="hljs-number">100</span>_000)

random_checker = timeit.timeit(stmt=<span class="hljs-string">'random.random()'</span>,
                               setup=<span class="hljs-string">'import random'</span>,
                               number=<span class="hljs-number">100</span>_000)

print(<span class="hljs-string">f'Time of randint function is <span class="hljs-subst">{round(randint_checker,<span class="hljs-number">4</span>)}</span> '</span>
      <span class="hljs-string">f'\nTime of random function is <span class="hljs-subst">{round(random_checker,<span class="hljs-number">4</span>)}</span>'</span>)

print(<span class="hljs-string">f'We can clearly see <span class="hljs-subst">{<span class="hljs-string">"random function"</span> <span class="hljs-keyword">if</span> random_checker &lt; randint_checker <span class="hljs-keyword">else</span> <span class="hljs-string">"RandInt"</span>}</span>'</span>
      <span class="hljs-string">f' as high in performance.'</span>)
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706106040426/73bdd78a-1155-4720-82a6-e22aa4482a55.png" alt class="image--center mx-auto" /></p>
<p>Let me explain the code for a bit.</p>
<ol>
<li><p>The <code>stmt</code> parameter in <code>timeit.timeit</code> is the statement that will be executed and timed. In your case, it's the function calls <code>random.randint(0,5)</code> and <code>random.random()</code>.</p>
</li>
<li><p>The <code>setup</code> parameter is used to set up the environment before running the timed code. In your case, it imports the <code>random</code> module.</p>
</li>
<li><p>The <code>number</code> parameter specifies the number of times the statement should be executed for each timing measurement. By default it sets to 1 million</p>
</li>
<li><p>The results are printed, and the code determines which function is faster based on the execution times.</p>
</li>
</ol>
<p>Now let's get back to the real scenarios, eg: you wrote two functions to perform the same task and you want to find out which one is fast, In the example, we have two functions both used to generate the Fibonacci Series.</p>
<p>first 1</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_series</span>(<span class="hljs-params">n</span>):</span>
    fib_series = []
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(n):
        fib_series.append(a)
        a, b = b, a + b

    <span class="hljs-keyword">return</span> fib_series

<span class="hljs-comment"># Example: Print the first 10 numbers in the Fibonacci series</span>
n = <span class="hljs-number">10</span>
result = fibonacci_series(n)
print(<span class="hljs-string">f"Fibonacci Series up to <span class="hljs-subst">{n}</span> terms: <span class="hljs-subst">{result}</span>"</span>)
</code></pre>
<p>Second 2</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_generator</span>(<span class="hljs-params">n</span>):</span>
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>
    count = <span class="hljs-number">0</span>

    <span class="hljs-keyword">while</span> count &lt; n:
        <span class="hljs-keyword">yield</span> a
        a, b = b, a + b
        count += <span class="hljs-number">1</span>

<span class="hljs-comment"># Example: Print the first 10 numbers in the Fibonacci series using the generator</span>
n = <span class="hljs-number">10</span>
fibonacci_gen = fibonacci_generator(n)
result = list(fibonacci_gen)
print(<span class="hljs-string">f"Fibonacci Series up to <span class="hljs-subst">{n}</span> terms: <span class="hljs-subst">{result}</span>"</span>)
</code></pre>
<p>Let's check the performance</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> timeit


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_series</span>(<span class="hljs-params">n</span>):</span>
    fib_series = []
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(n):
        fib_series.append(a)
        a, b = b, a + b

    <span class="hljs-keyword">return</span> fib_series


<span class="hljs-comment"># Example: Print the first 10 numbers in the Fibonacci series using the generator</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_generator</span>(<span class="hljs-params">n</span>):</span>
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>
    count = <span class="hljs-number">0</span>

    <span class="hljs-keyword">while</span> count &lt; n:
        <span class="hljs-keyword">yield</span> a
        a, b = b, a + b
        count += <span class="hljs-number">1</span>


n = <span class="hljs-number">10</span>

checker_fs = timeit.timeit(stmt=<span class="hljs-string">'fibonacci_series(n = n)'</span>,
                           globals=globals())
checker_fg = timeit.timeit(stmt=<span class="hljs-string">'fibonacci_generator(n = n)'</span>,
                           globals=globals())

print(<span class="hljs-string">f'fibonacci_series: <span class="hljs-subst">{round(checker_fs, <span class="hljs-number">4</span>)}</span> '</span>
      <span class="hljs-string">f'\nfibonacci_generator: <span class="hljs-subst">{round(checker_fg, <span class="hljs-number">4</span>)}</span>'</span>)
print(<span class="hljs-string">f'<span class="hljs-subst">{<span class="hljs-string">"fibonacci series"</span> <span class="hljs-keyword">if</span> checker_fs&lt;checker_fg <span class="hljs-keyword">else</span> <span class="hljs-string">"fibonacci_generator"</span>}</span> '</span>
      <span class="hljs-string">f'is faster'</span>)
</code></pre>
<p>if your code snippet relies on global variables and you want to include those global variables in the execution context, you can use the <code>globals</code> parameter of the <code>timeit.timeit</code> function</p>
<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706105962094/3329c430-c4c3-4178-8bce-0c99bd7b6d86.png" alt class="image--center mx-auto" /></p>
<p><code>timeit</code> module also allows to <strong>repeat</strong> the test for specified times</p>
<pre><code class="lang-python">repeat_fs = timeit.repeat(stmt=<span class="hljs-string">'fibonacci_series(n = n)'</span>,
                          globals=globals(),
                          repeat=<span class="hljs-number">5</span>)

repeat_fg = timeit.repeat(stmt=<span class="hljs-string">'fibonacci_generator(n = n)'</span>,
                          globals=globals(),
                          repeat=<span class="hljs-number">5</span>)


print(<span class="hljs-string">f'Fibonacci_series: <span class="hljs-subst">{repeat_fs}</span>'</span>)
print(<span class="hljs-string">f'Fibonacci_generator: <span class="hljs-subst">{repeat_fg}</span>'</span>)
</code></pre>
<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706106940304/c2331d5e-033a-4560-a32f-47d44a33c6fc.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-cprofile-for-the-entire-execution-of-a-program">Cprofile - For the entire execution of a program</h2>
<ul>
<li><p><strong>Purpose:</strong><code>cProfile</code> is used for profiling the entire execution of a program and provides detailed information about the time spent in each function call.</p>
</li>
<li><p><strong>Usage:</strong> It's suitable for identifying performance bottlenecks, understanding function call patterns, and getting a more in-depth analysis of where the program spends its time.</p>
</li>
</ul>
<p><code>cProfile</code> is a built-in module in Python that provides a set of functions for profiling the performance of a Python program. Profiling helps you understand how much time your program spends on different functions, which can be useful for identifying bottlenecks and optimizing your code.</p>
<p>Let's see this in practice.</p>
<p>We are going to make a fake website backend, so it's going to make API requests it's going to be able to refresh the page, and so on just, we can see where our program can be improved and we can get how long it took to execute certain parts of the code.</p>
<p>So first we go ahead and create an API call and we know API calls are very costly functions.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> cProfile
<span class="hljs-keyword">import</span> time


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">api_call</span>():</span>
    time.sleep(<span class="hljs-number">2</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>
</code></pre>
<p>Here, when we have some data, we want to process it, so we are going to create a function called process_data.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_data</span>():</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span> ** <span class="hljs-number">7</span>):
        <span class="hljs-keyword">pass</span>
</code></pre>
<p>then sort the data and let's reload the data.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sort_data</span>():</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span> ** <span class="hljs-number">8</span>):
        <span class="hljs-keyword">pass</span>
    process_data()

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">reload_page</span>():</span>
    process_data()
    sort_data()
    time.sleep(<span class="hljs-number">2</span>)
</code></pre>
<p>let's execute in the main</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    api_call()
    sort_data()
    reload_page()
</code></pre>
<p>The real benchmarking.</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    cProfile.run(<span class="hljs-string">'main()'</span>, sort=<span class="hljs-string">'cumtime'</span>)
</code></pre>
<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706175246658/d5872888-5120-49db-9518-e6a18b55fc6c.png" alt class="image--center mx-auto" /></p>
<p>Let me explain to you what's in the output.</p>
<ol>
<li><p><strong>General Information:</strong></p>
<ul>
<li><code>13 function calls in 6.183 seconds</code>: This line indicates that there were 13 function calls in the entire program, and the program took 6.183 seconds to execute.</li>
</ul>
</li>
<li><p><strong>Ordered by Cumulative Time:</strong></p>
<ul>
<li><code>Ordered by: cumulative time</code>: The output is sorted by cumulative time, i.e., the total time spent in a function and its sub-functions.</li>
</ul>
</li>
<li><p><strong>Columns Explanation:</strong></p>
<ul>
<li><p><code>ncalls</code>: The number of calls made to the function.</p>
</li>
<li><p><code>tottime</code>: The total time spent in the function excluding time spent in sub-functions.</p>
</li>
<li><p><code>percall</code>: The average time per call (excluding sub-functions).</p>
</li>
<li><p><code>cumtime</code>: The cumulative time spent in the function and its sub-functions.</p>
</li>
<li><p><code>percall</code>: The average cumulative time per call.</p>
</li>
<li><p><code>filename:lineno(function)</code>: Information about the function, including the filename, line number, and function name.</p>
</li>
</ul>
</li>
<li><p><strong>Specific Lines Explained:</strong></p>
<ul>
<li><p><code>{built-in method builtins.exec}</code> and <code>&lt;string&gt;:1(&lt;module&gt;)</code>: Overhead added by the Python interpreter for executing the code.</p>
</li>
<li><p><code>cprofile_</code><a target="_blank" href="http://module.py:28"><code>module.py:28</code></a><code>(main)</code>: Time spent in the <code>main</code> function (the entry point of your script).</p>
</li>
<li><p><code>{built-in method time.sleep}</code>: Time spent in the <code>time.sleep</code> function calls.</p>
</li>
<li><p><code>cprofile_</code><a target="_blank" href="http://module.py:22"><code>module.py:22</code></a><code>(reload_page)</code>: Time spent in the <code>reload_page</code> function, including time spent in <code>sort_data</code> and <code>process_data</code>.</p>
</li>
<li><p><code>cprofile_</code><a target="_blank" href="http://module.py:16"><code>module.py:16</code></a><code>(sort_data)</code>: Time spent in the <code>sort_data</code> function, including time spent in <code>process_data</code>.</p>
</li>
<li><p><code>cprofile_</code><a target="_blank" href="http://module.py:5"><code>module.py:5</code></a><code>(api_call)</code>: Time spent in the <code>api_call</code> function.</p>
</li>
<li><p><code>cprofile_</code><a target="_blank" href="http://module.py:10"><code>module.py:10</code></a><code>(process_data)</code>: Time spent in the <code>process_data</code> function.</p>
</li>
</ul>
</li>
<li><p><strong>Profiler Disable Line:</strong></p>
<ul>
<li><code>{method 'disable' of '_lsprof.Profiler' objects}</code>: Indicates that the profiler was successfully disabled.</li>
</ul>
</li>
</ol>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>sub-function</strong>: In the context of <code>cProfile</code> and profiling tools in general, the term "subfunction" refers to a function that is called from another function. When a function calls another function, the second function becomes a subfunction of the calling function.</div>
</div>

<p>CProfile is not suitable for the function with a shorter execution time but effective if you want to know other details like the number of function calls and inbuilt functions.</p>
<p>Let me show, what I mean by that.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> cProfile


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_series</span>(<span class="hljs-params">n</span>):</span>
    fib_series = []
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>

    <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(n):
        fib_series.append(a)
        a, b = b, a + b

    <span class="hljs-keyword">return</span> fib_series


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibonacci_generator</span>(<span class="hljs-params">n</span>):</span>
    a, b = <span class="hljs-number">0</span>, <span class="hljs-number">1</span>
    count = <span class="hljs-number">0</span>

    <span class="hljs-keyword">while</span> count &lt; n:
        <span class="hljs-keyword">yield</span> a
        a, b = b, a + b
        count += <span class="hljs-number">1</span>


n = <span class="hljs-number">10</span>

<span class="hljs-comment"># Profile the execution of fibonacci_series and fibonacci_generator</span>
profiler = cProfile.Profile()
profiler.enable()
result_series = fibonacci_series(n)
result_generator = list(fibonacci_generator(n))
profiler.disable()
profiler.print_stats(sort=<span class="hljs-string">'cumtime'</span>)
</code></pre>
<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1706176966282/9d9fc1b4-3525-4ee4-96ba-67c7ea3a51ea.png" alt class="image--center mx-auto" /></p>
<p>You can see it's showing zero seconds, but in <code>timeit</code> , it was showing the accurate execution time.</p>
<p>If the <code>cProfile</code> output is showing 0 seconds for all functions, it might indicate that the execution time of your code is extremely short, possibly below the resolution of the timer used by <code>cProfile</code>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p><strong>Choosing Between</strong><code>timeit</code><strong>and</strong><code>cProfile</code>:</p>
<ul>
<li><p>If you want a quick measurement of the execution time for a specific piece of code, use <code>timeit</code>.</p>
</li>
<li><p>If you need detailed information about function calls and where time is spent in your entire program, use <code>cProfile</code>.</p>
</li>
</ul>
<p>In practice, both tools can complement each other. You might use <code>timeit</code> for initial quick measurements and then use <code>cProfile</code> for more in-depth analysis if you identify potential performance issues.</p>
<p>By combining these tools, developers can adopt a two-tiered approach. Start with <code>timeit</code> for initial assessments, identifying potential areas of concern. Subsequently, use <code>cProfile</code> to delve deeper into the code, gaining insights into function-level performance and optimizing critical sections.</p>
<p>Ultimately, the judicious use of <code>timeit</code> and <code>cProfile</code> empowers developers to strike a balance between quick assessments and thorough profiling, leading to well-optimized and high-performance Python code.</p>
<p><img src="https://i.pinimg.com/originals/59/d1/71/59d17122934ef58fb24fda82d8854214.gif" alt="Wave Bye Sticker - Wave Bye Goodbye - Discover &amp; Share GIFs | Cutie  cat-chan, Cute cat gif, Cute anime cat" class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Seamless Integration: A Practical Guide to Jenkins CI/CD for Django Development]]></title><description><![CDATA[In this article, I am going to explain you through the process of combining Django and Jenkins for a smooth CI/CD pipeline in your Python web projects. If you're already familiar with the basics of CI/CD and pipelines, feel free to skip and you can j...]]></description><link>https://vishnutiwari.dev/seamless-integration-a-practical-guide-to-jenkins-cicd-for-django-development</link><guid isPermaLink="true">https://vishnutiwari.dev/seamless-integration-a-practical-guide-to-jenkins-cicd-for-django-development</guid><category><![CDATA[djangojenkins]]></category><category><![CDATA[Django]]></category><category><![CDATA[Jenkins]]></category><category><![CDATA[Pipeline]]></category><category><![CDATA[nginx]]></category><category><![CDATA[Gunicorn]]></category><category><![CDATA[ec2]]></category><category><![CDATA[CI/CD]]></category><category><![CDATA[development]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Python]]></category><category><![CDATA[django rest framework]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[integration]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Sun, 21 Jan 2024 19:07:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705857838136/e75058b9-1e86-4e23-a21d-3c1c3ae10e5d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I am going to explain you through the process of combining Django and Jenkins for a smooth CI/CD pipeline in your Python web projects. If you're already familiar with the basics of CI/CD and pipelines, feel free to skip and you can jump to the steps. For those just diving in, I'll briefly cover the essentials before we get into the hands-on steps</p>
<h2 id="heading-what-is-cicd">What is CI/CD?</h2>
<p>CI/CD stands for Continuous Integration and Continuous Deployment (or Continuous Delivery), and it represents a set of best practices, principles, and automated processes aimed at improving the software development and delivery lifecycle.</p>
<p><strong>Yeah, but what is this and why should we use it?</strong></p>
<p><strong>Continuous Integration (CI):</strong> Imagine a team of developers working on a mobile app. Each developer is responsible for adding new features or fixing bugs. In a CI setup, every time a developer finishes their work on a particular feature or bug fix, they integrate their code changes into a shared code repository, let's say on GitHub. Automated tests are then triggered to ensure that the new code doesn't break the existing functionality. If any issues are found, the team is notified immediately, allowing them to fix the problems early in the development process.</p>
<p><strong>Continuous Deployment (CD):</strong> Now, consider the same mobile app project, but this time with continuous deployment. Once the code changes pass all the automated tests in the CI phase, the updated app is automatically deployed to a staging environment or even directly to production. Users can start using the new features or bug fixes almost immediately. This rapid deployment ensures that the latest improvements are available to users as soon as they are deemed stable and functional.</p>
<p><strong>Continuous Delivery (CD):</strong> In a continuous delivery scenario, the process is similar to continuous deployment, but with an additional manual step before deploying to the production environment. After passing automated tests in the CI phase, the updated app is deployed to a staging environment. A team member or a designated person then reviews the changes and decides when to manually trigger the deployment to the production environment. This adds a layer of human oversight before changes go live.</p>
<h3 id="heading-what-is-a-pipeline">What is a pipeline?</h3>
<p>A pipeline refers to a set of automated processes and steps through which software code progresses from development to deployment. This sequence of steps is known as a "pipeline" because it represents a flow of activities, typically organized in a linear or branching structure. The purpose of a pipeline is to automate and streamline the software delivery process, making it more efficient, consistent, and reliable.</p>
<p>Let's consider a <strong>simplified example</strong> of a continuous integration and deployment (CI/CD) pipeline for a web application using a <strong>hypothetical e-commerce project.</strong></p>
<ol>
<li><p><strong>Source Code Repository:</strong></p>
<ul>
<li>Developers collaborate on the project and store the source code in a version control repository, such as Git on GitHub.</li>
</ul>
</li>
<li><p><strong>Continuous Integration (CI) Pipeline:</strong></p>
<ul>
<li><p>When a developer pushes changes to the repository, it triggers the CI pipeline.</p>
</li>
<li><p>The CI pipeline consists of the following stages and tasks:</p>
<ul>
<li><p><strong>Build Stage:</strong></p>
<ul>
<li>Compiles the source code into executable binaries.</li>
</ul>
</li>
<li><p><strong>Test Stage:</strong></p>
<ul>
<li>Runs automated tests to ensure that the new code changes haven't introduced regressions or errors.</li>
</ul>
</li>
<li><p><strong>Code Quality Stage:</strong></p>
<ul>
<li>Checks for coding standards, code complexity, and other code quality metrics.</li>
</ul>
</li>
<li><p><strong>Artifact Generation:</strong></p>
<ul>
<li>Creates deployable artifacts, such as a packaged web application.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Continuous Deployment (CD) Pipeline:</strong></p>
<ul>
<li><p>If all the tasks in the CI pipeline are successful, it triggers the CD pipeline.</p>
</li>
<li><p>The CD pipeline consists of the following stages and tasks:</p>
<ul>
<li><p><strong>Deploy to Staging:</strong></p>
<ul>
<li><p>Takes the artifacts from the CI pipeline and deploys them to a staging environment.</p>
</li>
<li><p>Automated tests are run in the staging environment to verify the application's behavior in a production-like setting.</p>
</li>
</ul>
</li>
<li><p><strong>Manual Approval:</strong></p>
<ul>
<li>A manual approval step where a team member reviews the changes in the staging environment and decides whether to proceed with deployment to production.</li>
</ul>
</li>
<li><p><strong>Deploy to Production:</strong></p>
<ul>
<li><p>If the manual approval is granted, the artifacts are deployed to the production environment.</p>
</li>
<li><p>The application is now live for end-users.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Rollback Mechanism:</strong></p>
<ul>
<li><p>The pipeline includes a rollback mechanism in case issues are discovered in the production environment after deployment.</p>
</li>
<li><p>If a problem occurs, the team can trigger a rollback to the previous version of the application.</p>
</li>
</ul>
</li>
<li><p><strong>Monitoring and Logging:</strong></p>
<ul>
<li><p>Throughout the pipeline, monitoring and logging tools are used to track the progress of each stage and capture any issues or anomalies.</p>
</li>
<li><p>Metrics related to application performance, errors, and resource utilization are monitored in both staging and production environments.</p>
</li>
</ul>
</li>
<li><p><strong>Automation Tool:</strong></p>
<ul>
<li>Jenkins, a popular CI/CD automation tool, is used to define and execute the pipeline stages and tasks.</li>
</ul>
</li>
</ol>
<p>In this example, the CI/CD pipeline automates the process from code changes to deployment, ensuring that the application is built, tested, and deployed consistently. The staging environment acts as a testing ground before changes are applied to the production environment, and the pipeline includes mechanisms for both manual approval and rollback to maintain control and reliability.</p>
<p>So Now we understand the basic let's get started with step by step on how to setup the ci/cd pipeline with Jenkins.</p>
<hr />
<h1 id="heading-lets-start">Let's Start</h1>
<p>For the first step, you need to choose a machine; you can either use your own machine or any virtual server for hosting your application and building the pipeline. Since I want it to be real, I am going with an EC2 instance (an AWS service).</p>
<h2 id="heading-step-1-setting-up-a-ec2-instance">Step 1 : Setting up a EC2 instance</h2>
<p>Setting up an ec2 instance is pretty straight forward.</p>
<ol>
<li><p>Go to AWS console <a target="_blank" href="https://aws.amazon.com/">AWS Amazon</a> and sign in with your account.</p>
</li>
<li><p>Go to EC2 and click on launch instance.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705576569572/3e80d966-1fe5-4500-a988-1cb87c89dbe2.png" alt class="image--center mx-auto" /></p>
<p> Now give a name, select your machine type, create or select a key pair(for SSH login), rest you can select according to your project infrastructure or use default settings. (I used free tier ubuntu)</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705576935988/e74cfea6-a90d-4af2-b88f-a0b221771dc4.png" alt class="image--center mx-auto" /></p>
<p> Launch the instance and wait for some minutes to boot up the server.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705577025312/1ae20310-b8b0-41cd-bdfd-5aefe2f21e39.png" alt class="image--center mx-auto" /></p>
<p> Great! Instance is successfully created, we completed the first step.</p>
</li>
</ol>
<h2 id="heading-step-2-connect-with-the-instance">Step 2: Connect with the instance.</h2>
<p>Connect with ec2 instance is also a very easy step. We going to connect with our server using ssh keys.</p>
<ol>
<li><p>Just click on the instance id.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705577442671/095e13bf-c436-4e23-ba0a-5b7dbd07b922.png" alt /></p>
<p> Click on connect on the upper-right.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705577640961/d32fb18d-e6be-4c51-be05-72c15ed70966.png" alt class="image--center mx-auto" /></p>
<p> Go to the SSH client, where there are clear instructions on how to connect through SSH to the instance.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705577966303/da8413cd-5eb1-410b-98e8-06a0231181c9.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now after giving the permission to our key pair and running the command, we will be connected to our instance, like this.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705578167594/699189ac-839a-4185-8229-5dc457055056.png" alt /></p>
</li>
<li><p>Great! Step 2 is done.</p>
</li>
</ol>
<h2 id="heading-step-3-installing-jenkins">Step 3: Installing Jenkins</h2>
<p>For installing Jenkins on our <strong>ec2 instance</strong>, java is necessary because Jenkins is built using Java and runs as a Java application.</p>
<ol>
<li><p><strong>Updating and Upgrading the system</strong>.(will take some time Approx.: 2-3 min)</p>
<pre><code class="lang-bash"> sudo apt-get update -y
</code></pre>
<p> Running <code>sudo apt-get update</code> on a fresh EC2 Linux instance is a best practice to ensure that your package manager has the latest information about available software packages.</p>
<pre><code class="lang-bash"> sudo apt-get upgrade -y
</code></pre>
<p> <code>sudo apt-get upgrade</code> is used to install the latest versions of all packages currently installed on the system. It does not install new packages; instead, it upgrades the existing ones to their latest versions.</p>
</li>
<li><p><strong>Java Installation</strong></p>
<pre><code class="lang-bash"> sudo apt-get install openjdk-17-jre -y
</code></pre>
<p> I am installing open-jdk version 17 as it is the latest. You may use different one according to when you are reading this article. For checking support policy for Jenkins Visit <a target="_blank" href="https://www.jenkins.io/doc/book/platform-information/support-policy-java/">Support Policy Java Jenkins</a> .</p>
</li>
<li><p><strong>Jenkins Installation</strong></p>
<pre><code class="lang-bash"> sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
   https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
</code></pre>
<pre><code class="lang-bash"> <span class="hljs-built_in">echo</span> deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
   https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
   /etc/apt/sources.list.d/jenkins.list &gt; /dev/null
</code></pre>
<pre><code class="lang-bash"> sudo apt-get update -y
</code></pre>
<pre><code class="lang-bash"> sudo apt-get install jenkins -y
</code></pre>
<p> Run these 4 command one by one<br /> <strong>OR</strong></p>
<p> create a script called install_jenkins.sh</p>
<p> Add the following content</p>
<pre><code class="lang-bash"> <span class="hljs-comment">#!/bin/bash</span>

 sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
   https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key

 <span class="hljs-built_in">echo</span> deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
   https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
   /etc/apt/sources.list.d/jenkins.list &gt; /dev/null

 sudo apt-get update
 sudo apt-get install jenkins
</code></pre>
<p> Make the script executable:</p>
<pre><code class="lang-bash"> chmod +x install_jenkins.sh
</code></pre>
<p> <strong>Run the Script:</strong></p>
<pre><code class="lang-bash"> ./install_jenkins.sh
</code></pre>
<p> This will run all four commands sequentially.</p>
<p> Visit <a target="_blank" href="https://www.jenkins.io/doc/book/installing/linux/">Jenkins Installation Linux</a> for more info.</p>
</li>
<li><p><strong>Jenkins has been successfully installed.</strong></p>
</li>
</ol>
<h2 id="heading-step-4-django-project-setup">Step 4: Django Project Setup</h2>
<ol>
<li><p><strong>Create a virtual env for your project in your local machine or wherever you primarily storing the code like GitHub or Bitbucket etc.</strong></p>
<pre><code class="lang-python"> python3 -m venv env
</code></pre>
<p> Activate it</p>
<pre><code class="lang-python"> source env/bin/activate
 <span class="hljs-comment"># OR</span>
 env/Scripts/activate
</code></pre>
</li>
<li><p><strong>Create a requirements.txt file</strong></p>
<pre><code class="lang-plaintext"> django
 gunicorn
</code></pre>
<p> Add all the dependencies in it which is required to run your project for eg: if you using API, add djangorestframework , pillow (if your models have image field or file field ) etc.</p>
</li>
<li><p><strong>Install the requirements</strong> in your virtual environment (Optional: if you want to run your project locally)</p>
<pre><code class="lang-python"> pip install -r requirements.txt
</code></pre>
<p> check the installed package by</p>
<pre><code class="lang-python"> pip freeze
</code></pre>
</li>
<li><p><strong>Add .gitignore</strong></p>
<pre><code class="lang-plaintext"> env
 .idea
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
 *$py.class
</code></pre>
<p> <strong>Note</strong> : Don't forget to add .<strong>env</strong> file or any file which is storing any kind of DB config or API keys.</p>
</li>
</ol>
<h2 id="heading-step-5-starting-jenkins">Step 5: Starting Jenkins</h2>
<p>Our Jenkins is installed in the server, and let's start it.</p>
<ul>
<li><p><strong>Starting the Jenkins server</strong></p>
<pre><code class="lang-plaintext">  sudo systemctl daemon-reload
</code></pre>
<pre><code class="lang-plaintext">  sudo systemctl start jenkins
</code></pre>
<pre><code class="lang-plaintext">  sudo systemctl status jenkins
</code></pre>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705583373003/ab6b3cdd-ea20-444b-ac54-91bfff5290e0.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
<p><strong>Accessing the Jenkins through browser</strong></p>
<p>Jenkins uses port 8080 for web access. When you install Jenkins and start the Jenkins server, it will listen on port 8080 for incoming HTTP requests.</p>
<p>By default, Jenkins uses 8080</p>
<p>For accessing Jenkins on the browser, copy your machine Ip address, in our case we are using ec2 instance so we need to give the permission to expose the port (and if you are doing this on your local machine you can skip this process), so copy the address and go to this url.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705584295472/fde59a84-14d0-4b76-ac79-c2e5e27908c0.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-plaintext">http://your-server-ip:8080
or if using local machine
http://localhost:8080
</code></pre>
<p>In our case, the security is not setup for port 8080. let's set it up in aws console.</p>
<ul>
<li><p>Go to security tab.</p>
</li>
<li><p>Add the rule for 8080 like this</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705584744227/bfa441f5-e661-4e67-9aaa-7971f3d821fe.png" alt class="image--center mx-auto" /></p>
<p>Now try to access the URL.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705584803966/0d0d7627-ae7a-4121-be32-1d7ebd7314a2.png" alt class="image--center mx-auto" /></p>
<p><strong>Unlocking the Jenkins</strong></p>
<pre><code class="lang-plaintext"> sudo cat /var/lib/jenkins/secrets/initialAdminPassword
</code></pre>
<p>copy the password and enter it.</p>
<p>And select Install Suggested Plugins</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705585229246/adb0cbf7-55a3-4cdf-9f04-f43493785a90.png" alt class="image--center mx-auto" /></p>
<p>Looks like the installation is successful.</p>
<h2 id="heading-step-6-adding-env-setup-file">Step 6: Adding env setup file</h2>
<p>Let's make the environment setup file to setup the virtual environment and logs.</p>
<p>Make a file called envsetup.sh</p>
<pre><code class="lang-plaintext">#!/bin/bash

# Check if virtualenv is installed
if command -v virtualenv &amp;&gt; /dev/null; then
    echo "virtualenv is already installed."
else
    echo "Installing virtualenv......"
    sudo apt install -y python3-virtualenv
fi


if [ -d "env" ]
then
    echo "Python virtual environment exists."
else
    echo "Creating a virtual environment"
    virtualenv env
fi

echo "The current directory"
echo $PWD
echo -e "\n\n\n"

echo "Activating the virtual environment"
source env/bin/activate
echo -e "\n\n\n"


# Check if pip3 is installed
echo "Checking for pip3 installation"
if command -v pip3 &amp;&gt; /dev/null; then
    echo "pip3 is already installed."
else
    echo "Installing pip3......."
    sudo apt install -y python3-pip
fi

echo -e "\n\n\n"
echo "Installing Requirements...."
pip3 install -r requirements.txt
echo "Requirements Installed."
echo -e "\n\n\n"

echo "Checking for logs"
if [ -d "logs" ]
then
    echo "Log folder exists."
else
    echo "Creating Logs"
    mkdir logs
    touch logs/error.log logs/access.log
fi

echo -e "\n\n\n"
echo "Giving Permission"
sudo chmod -R 777 logs
echo -e "\n\n\n"
echo "*********Script Ended************"
</code></pre>
<p><strong>File Hierarchy</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705586141750/ed40c879-5945-4e6c-aee7-8b3f560cfde1.png" alt class="image--center mx-auto" /></p>
<p>Let me explain what we did inside this file</p>
<ol>
<li><strong>Check for the existence of a Python virtual environment (</strong><code>env</code>):</li>
</ol>
<ul>
<li><p>Checks if the directory named "env" (presumably a Python virtual environment) exists.</p>
</li>
<li><p>If it exists, prints a message stating that the virtual environment exists.</p>
</li>
<li><p>If it doesn't exist, creates a Python virtual environment using <code>python3 -m venv env</code>.</p>
</li>
</ul>
<ol>
<li><p><strong>Activate the Python virtual environment:</strong></p>
<ul>
<li>Activates the virtual environment using <code>source env/bin/activate</code>.</li>
</ul>
</li>
<li><p><strong>Install Python dependencies from</strong> <code>requirements.txt</code>:</p>
<ul>
<li>Uses <code>pip3</code> to install the dependencies listed in the <code>requirements.txt</code> file.</li>
</ul>
</li>
<li><p><strong>Set permissions for the "logs" folder:</strong></p>
<ul>
<li><p>Changes the permissions of the "logs" folder and its contents to allow read, write, and execute permissions for everyone (<code>chmod -R 777 logs</code>).</p>
</li>
<li><p>Note: Using <code>chmod 777</code> provides full read, write, and execute permissions to everyone, which may have security implications</p>
</li>
</ul>
</li>
</ol>
<p>Feel free to change any of the code according to your convenience.</p>
<h2 id="heading-step-7-adding-jenkinsfile">Step 7: Adding Jenkinsfile</h2>
<p>Now create a file named "<strong>Jenkinsfile</strong>".</p>
<h3 id="heading-what-is-jenkinsfile">What is Jenkinsfile?</h3>
<p>A Jenkinsfile is a text file that defines the steps or stages of a Jenkins Pipeline. A Jenkins Pipeline is a suite of plugins that supports implementing and integrating continuous delivery pipelines into Jenkins.</p>
<p>Let's create a pipeline, create a file named Jenkinsfile</p>
<pre><code class="lang-plaintext">pipeline{
    agent any
    stages {

        stage('Setup Python Virtual ENV for dependencies'){

      steps  {
            sh '''
            chmod +x envsetup.sh
            ./envsetup.sh
            '''}
        }
        stage('Setup Gunicorn Setup'){
            steps {
                sh '''
                chmod +x gunicorn.sh
                ./gunicorn.sh
                '''
            }
        }
        stage('setup NGINX'){
            steps {
                sh '''
                chmod +x nginx.sh
                ./nginx.sh
                '''
            }
        }
    }
}
</code></pre>
<p><strong>Note</strong>: We will add gunicorn.sh and nginx.sh file later. Also I will explain why to use Nginx and Gunicorn.</p>
<h2 id="heading-adding-gunicorn-setup-file">Adding gunicorn setup file</h2>
<p>Create a file name as "gunicorn.sh"</p>
<h3 id="heading-what-is-gunicorn">What is gunicorn?</h3>
<p>Gunicorn (Green Unicorn) is a WSGI (Web Server Gateway Interface) server for running Python web applications.</p>
<p>Imagine you have a Python web application, like a website built with a framework such as Flask or Django. Now, when someone wants to visit your website, their browser sends a request to your server, asking for the webpage. Here's where Gunicorn comes into play:</p>
<ul>
<li><p>Gunicorn acts like a traffic cop for your website. It takes the incoming requests from users and directs them to the appropriate part of your Python web application.</p>
</li>
<li><p>Gunicorn is good at handling many requests at the same time. It's like having multiple waiters at a restaurant. While one waiter takes an order, others can serve food to different tables, making the overall service faster.</p>
</li>
<li><p>Production WSGI servers are designed to handle multiple requests concurrently, making them suitable for scaling in a production environment. Django's development server is single-threaded and not optimized for handling a large number of simultaneous requests.</p>
</li>
</ul>
<p>It handles incoming requests, manages many requests at once, and ensures smooth updates or restarts. It's the waiter that takes orders (requests) and ensures the chef (your web app) serves the food (webpages) efficiently, even when the restaurant (your website) is busy.</p>
<pre><code class="lang-plaintext">#!/bin/bash

source env/bin/activate

cd /var/lib/jenkins/workspace/directory_name/project_name

python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py collectstatic -- no-input

echo "Migrations done"

cd /var/lib/jenkins/workspace/directory_name

sudo cp -rf gunicorn.socket /etc/systemd/system/
sudo cp -rf gunicorn.service /etc/systemd/system/

echo "$USER"
echo "$PWD"



sudo systemctl daemon-reload
sudo systemctl start gunicorn

echo "Gunicorn has started."

sudo systemctl enable gunicorn

echo "Gunicorn has been enabled."

sudo systemctl restart gunicorn


sudo systemctl status gunicorn
</code></pre>
<p>Now let's add the gunicorn.socket and gunicorn.service file.</p>
<p><strong>gunicorn.socket</strong></p>
<pre><code class="lang-plaintext">[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
SocketUser=www-data
# Optionally restrict the socket permissions even more.
# SocketMode=600

[Install]
WantedBy=sockets.target
</code></pre>
<p><strong>gunicorn.service</strong></p>
<pre><code class="lang-plaintext">[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=root
Group=www-data
WorkingDirectory=/var/lib/jenkins/workspace/django-cicd/app
ExecStart=/var/lib/jenkins/workspace/django-cicd/env/bin/gunicorn 
           --workers 1 
           --log-level debug 
           --error-logfile /var/lib/jenkins/workspace/django-cicd/error.log 
           --bind unix:/run/gunicorn.sock app.wsgi:application

[Install]
WantedBy=multi-user.target


[Install]
WantedBy=multi-user.target
</code></pre>
<p><strong>Change the paths according to your project structure. Don't worry i will tell how to know the path and all later. You can continue without updating the path.</strong></p>
<h2 id="heading-step-8-reverse-proxynginx-setup">Step 8: Reverse Proxy(Nginx) Setup</h2>
<p>Now let's setup nginx as our reverse proxy but for those who don't know</p>
<h3 id="heading-what-is-nginx-and-why-we-are-using">What is Nginx and Why we are using?</h3>
<p>Nginx is a popular open-source web server and reverse proxy server that is widely used for hosting websites and applications. It is known for its high performance, stability, and scalability.</p>
<p>When using Django in a production environment, it's common to deploy it behind a combination of Nginx and Gunicorn. Here's why this combination is popular:</p>
<ol>
<li><p><strong>Nginx as a Reverse Proxy:</strong> Nginx can serve as a reverse proxy, handling client requests and forwarding them to Gunicorn. This allows Nginx to handle tasks like SSL termination, static file serving, and load balancing. Nginx is particularly efficient at serving static files, so offloading this task from Gunicorn can improve overall performance.</p>
</li>
<li><p><strong>Handling Static Files:</strong> Django is a powerful web framework, but it may not be as efficient as dedicated web servers like Nginx at serving static files (e.g., images, stylesheets, JavaScript). By using Nginx to serve static content, Gunicorn can focus on handling dynamic content and application logic.</p>
</li>
</ol>
<p>Nginx is configured to act as a reverse proxy for your Django application served by Gunicorn. It handles static files, forwards dynamic requests to Gunicorn, and provides additional features like load balancing and security</p>
<hr />
<p>Now let's back to work.</p>
<p>Create a file named "nginx.sh".</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

sudo cp -rf app.conf /etc/nginx/sites-available/app
chmod 710 /var/lib/jenkins/workspace/django-cicd

sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled
sudo nginx -t

sudo systemctl start nginx
sudo systemctl <span class="hljs-built_in">enable</span> nginx

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Nginx has been started"</span>

sudo systemctl status nginx
</code></pre>
<p>Now create an app.conf file</p>
<pre><code class="lang-plaintext">server {
  listen 80;
  server_name IP;
  error_log /var/lib/jenkins/workspace/django-cicd/logs/error.log;
  access_log /var/lib/jenkins/workspace/django-cicd/logs/access.log;

  location = /favicon.ico { access_log off; log_not_found off; }

  location /static/ {
    root /var/lib/jenkins/workspace/django-cicd;
  }

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unix:/run/gunicorn.sock;
    }
}
</code></pre>
<p>change the ip with the ec2 instance ip.</p>
<p><strong>Installing NGINX</strong></p>
<pre><code class="lang-bash">sudo apt-get install nginx
</code></pre>
<pre><code class="lang-bash">sudo systemctl start nginx
</code></pre>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> nginx
</code></pre>
<pre><code class="lang-bash">sudo systemctl status nginx
</code></pre>
<p>Now if status is active it means, it is setup properly.</p>
<h2 id="heading-step-9-configuring-the-pipeline">Step 9: Configuring The Pipeline</h2>
<p>The Jenkins is already installed and unlocked, so let's get started with creating our first Admin User.</p>
<ol>
<li><p>Access Jenkins through browser.</p>
</li>
<li><p>Fill the form</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705829001628/b1d05671-7db9-4c28-a059-7d25b3e12364.png" alt class="image--center mx-auto" /></p>
<p> Configure the URL(am using as it is.)</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705829130707/e9d95591-ca58-40aa-b889-0dd8969c9c9c.png" alt class="image--center mx-auto" /></p>
<p> Click on Start using Jenkins.</p>
</li>
<li><p>Now you will be on dashboard.</p>
</li>
</ol>
<p>Now upload your project on any VCS like GitHub or Bitbucket. And now we are good to go with configuring our first pipeline for the project.</p>
<ol>
<li><p>Go to the dashboard.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705830178427/72124b4f-9eed-4150-b822-2eb3996b002b.png" alt class="image--center mx-auto" /></p>
<p> Click on New Item.</p>
</li>
<li><p>Enter the name of your project and click on pipeline.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705830270700/bd2de08e-57e8-4b27-aa85-acebdabeafca.png" alt class="image--center mx-auto" /></p>
<p> Now In General section, give a meaningful description and use option Discard Old Builds.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705831186708/a4569a71-3e3a-4c56-9964-814de8dbe11f.png" alt class="image--center mx-auto" /></p>
<p> You can leave it everything as it is and go to Pipeline.</p>
</li>
<li><p>Give information like this.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705831663371/7a848ec7-8919-421a-9a2b-537e8c2fbce4.png" alt class="image--center mx-auto" /></p>
<p> For credentials, create a personal access token and copy it.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705831998645/e0f0b520-476d-482d-9d19-04bada893069.png" alt class="image--center mx-auto" /></p>
<p> And Paste it like this in Jenkins.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705832235217/82cc4cc4-45df-46c2-8495-d1304aa4bd98.png" alt class="image--center mx-auto" /></p>
<p> Provide the branch name and click on save.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705832384018/73959b86-1414-4871-8001-33a5021d9bf1.png" alt class="image--center mx-auto" /></p>
<p> Later, i will tell on how to setup for auto build trigger on code push.</p>
</li>
</ol>
<h2 id="heading-step-10-giving-access-to-jenkin-user">Step 10: Giving access to Jenkin User</h2>
<p>We used a lot of sudo in our scripts. And our user is Jenkins and it doesn't have sudo privilege to run those commands also we are not providing any password.</p>
<p>so let's add Jenkins to our sudoers list.</p>
<ol>
<li><p>Run this command in your server.</p>
<pre><code class="lang-bash"> sudo vi /etc/sudoers
</code></pre>
</li>
<li><p>Copy this line</p>
<pre><code class="lang-bash"> jenkins ALL=(ALL) NOPASSWD: ALL
</code></pre>
</li>
<li><p>Paste like this and save it.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705835108826/70f81dfc-5e08-4159-9b7e-4f23b5df844a.png" alt /></p>
</li>
</ol>
<h2 id="heading-step-11-refactoring-the-code">Step 11: Refactoring the code</h2>
<p>Now, this is a crucial step for efficiently building a pipeline. If you have followed all the steps with me, I am confident that you may encounter errors when starting the build.</p>
<p>Let's address and fix some common issues:</p>
<ol>
<li><p><strong>File Path of Your Project:</strong> Ensure that the file paths in your scripts and configuration files accurately reflect the structure of your project. Copy the paths from the console output if needed, and update them in your scripts.</p>
</li>
<li><p><strong>Minor Bugs during Installation or Virtual Environment Activation:</strong> Examine the console output for any errors during the installation or activation of the virtual environment. If you come across minor bugs, investigate the error messages, search for solutions online, and consider making manual installations if necessary.</p>
</li>
<li><p><strong>Remove the default ngnix conf :</strong> It's possible that your Nginx is still utilizing the default settings, leading to the display of the default Nginx page in the browser.</p>
</li>
<li><p><strong>Giving Permission to static folder:</strong> Sometimes, Nginx may lack permission to use the static folder, leading to broken pages without styles or images. Ensure the static folder has proper permissions for Nginx to access and serve its contents."</p>
</li>
</ol>
<p>By addressing these issues, you'll enhance the robustness of your pipeline and increase the chances of a successful build.</p>
<p><strong>File path of your project</strong></p>
<p>In our project, there are approximately seven script files that use commands such as <code>python</code> <a target="_blank" href="http://manage.py"><code>manage.py</code></a> <code>makemigrations</code> or <code>migrate</code>, requiring the correct file path for your project.</p>
<p>In the bonus tip section, I will provide instructions on how to set this up for an enterprise-level application.</p>
<p>Now, run the build, examine the file path, and update it according to our project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840067792/0e3979a2-bbc2-42ac-afc8-775a0d708d47.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840124749/f6c53973-c290-49ef-87a2-3c1a201cbd1e.png" alt class="image--center mx-auto" /></p>
<p>Now select the build no. and go to console output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840212650/e10b8999-743c-4fda-ac7d-3ed447c44886.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840289446/cf0d8ec1-d5f7-4cc2-b6f3-9c61295dd8eb.png" alt class="image--center mx-auto" /></p>
<p>Copy the file path from the console output and examine it. You can navigate to this location to check for errors. Reference the path and update it in the scripts everywhere.</p>
<p>First, make changes in app.conf (two changes). Replace the file path with your project path.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840599292/328b13d3-76ec-4dee-b1b1-1af73f55ca3e.png" alt class="image--center mx-auto" /></p>
<p>Now in gunicorn.service file (2 changes)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840721993/9d2135f5-3b99-40bd-a970-a71c89b1ae5f.png" alt class="image--center mx-auto" /></p>
<p>in gunicorn.sh file (2 changes)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705840941590/216a9b3c-81ce-470e-9e7f-2c1f34b28899.png" alt class="image--center mx-auto" /></p>
<p>in ngnix.sh file (1 change)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705841361678/2f59e877-7740-488d-b8ca-8a14e18f3a7a.png" alt class="image--center mx-auto" /></p>
<p>After all these changes , your build should be successful.</p>
<p><strong>Minor bugs during the installation or activating the virtual environment</strong></p>
<p>If your build is not successful even after changing the file paths, examine the errors in the console output. Search the internet for solutions or consider installing the required tools manually.</p>
<p>If you encounter challenges activating the virtual environment, try doing it manually by navigating to the project location and creating a virtual environment from CLI.</p>
<p><strong>Remove the default ngnix conf</strong></p>
<ol>
<li><p>Go to /etc/ngnix/sites-enabled/</p>
</li>
<li><p>Delete the default config.</p>
<pre><code class="lang-bash"> rm -rf default
</code></pre>
</li>
<li><p>Now go to /etc/ngnix/sites-available/</p>
<pre><code class="lang-bash"> rm -rf default
</code></pre>
</li>
<li><p>Great ! We successfully deleted the default config and ngnix will use your app config.</p>
</li>
</ol>
<p><strong>Giving Permission to static folder</strong></p>
<p>The <code>www-data</code> user is commonly used by Nginx to run its worker processes. These worker processes handle incoming HTTP requests, and Nginx uses this user for security reasons. It's a good practice to have the Nginx worker processes run with a less privileged user like <code>www-data</code> to limit potential security risks.</p>
<pre><code class="lang-bash">sudo chown -R :www-data /var/
</code></pre>
<p>By following all these steps and addressing potential issues, your build should be successful. If you encounter any further challenges or errors during the process, carefully review the console output, search for solutions, and consider adapting the instructions based on the specific requirements and configurations of your project. Remember to thoroughly test your pipeline to ensure its reliability and efficiency.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705842664172/2e6f095b-ed3c-4338-9ae0-d073782a016a.png" alt class="image--center mx-auto" /></p>
<p>🎉 Congratulations! 🎉We have successfully setup the project.</p>
<h2 id="heading-step-12-accessing-the-project-on-browser">Step 12: Accessing The Project on Browser.</h2>
<p>Now, we need to ensure that our project is accessible on the internet. To achieve this, let's navigate to the AWS console. We'll need to allow traffic to view our application through HTTP or HTTPS, which typically uses ports 80 and 443. Let's proceed with the necessary configurations.</p>
<p>Go to security</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705843106343/8f7f211c-df0b-4cd2-9f39-7f666d20784d.png" alt class="image--center mx-auto" /></p>
<p>Click on Security Groups</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705843148534/63b8052f-8499-4d8e-97ce-702fa7b11057.png" alt class="image--center mx-auto" /></p>
<p>Edit the inbound rules</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705843186508/40819825-b900-40e0-91dd-b68245147da3.png" alt class="image--center mx-auto" /></p>
<p>Add rules like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705843324843/abdffccb-8d8a-49d2-b47a-73ef7ed2cf17.png" alt class="image--center mx-auto" /></p>
<p>Now try to access your app through the browser like this</p>
<p>If you encounter any issues, double-check the security group rules, the status of your Django application, and any potential firewall settings. Additionally, ensure that your AWS EC2 instance has the necessary IAM roles and permissions for internet access.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705850358809/74b3e99c-17f5-4cfe-8e0f-a785f21673fe.png" alt class="image--center mx-auto" /></p>
<p>🎉 Congratulations on successfully setting up your pipeline with Jenkins, Nginx, Gunicorn, and other components! Building and configuring a continuous integration and deployment (CI/CD) pipeline can be a complex task, so completing the setup is a significant achievement. 🚀💻</p>
<h1 id="heading-bonus-tips">Bonus Tips</h1>
<p>I'd like to share some bonus tips that I believe are crucial for setting up a pipeline in a corporate or tech giant environment. Having worked with esteemed companies such as IBM, Papa John's, and eBay, I feel qualified to offer insights based on the advice I received from my experienced colleagues.</p>
<ol>
<li><p><strong>Auto Build Trigger On Code Push</strong></p>
<p> Automatic triggering ensures that builds are initiated immediately upon code push. This provides developers with rapid feedback on the impact of their changes, helping identify and address issues early in the development lifecycle.</p>
<ul>
<li>Go to Configure</li>
</ul>
</li>
</ol>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705851771898/96506ee4-6dfd-4c0a-ac07-e30f41474378.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Provide the GitHub Project URL</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705851862520/b5e17729-88e6-4e64-9f81-d142d94e6cc6.png" alt class="image--center mx-auto" /></p>
<ul>
<li>Go to Build Trigger and Select GitHub hook trigger from GITScm Polling</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705852004052/b8fd3336-f95a-43a5-a726-78f6c1e2bc79.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Go to your project on GitHub &gt; Settings &gt; Webhooks</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705852228110/2200ad33-0306-4e99-b700-30864d67746b.png" alt class="image--center mx-auto" /></p>
<p>  Add webhook</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705852361321/c88874f2-9949-4f4c-90ae-256220264c97.png" alt class="image--center mx-auto" /></p>
<p>  Fill the form like this, provide the server-url</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1705852578724/d693888d-da43-4110-ae2c-bbe1dfdd7b18.png" alt class="image--center mx-auto" /></p>
<p>  Click on Add webhook</p>
</li>
<li><p>Great! We have successfully setup the Auto Build Trigger</p>
</li>
</ul>
<ol>
<li><p><strong>Use S3 Bucket for static file serving</strong></p>
<p> Serving static files directly from S3 reduces the load on your Django server. Nginx can be configured to serve static files from S3, allowing the Django server to focus on processing dynamic requests.</p>
<p> When deploying updates to your Django project, you don't need to transfer static files to multiple servers. The static files hosted on S3 are accessible from any server, simplifying the deployment process.<br /> When combined with Nginx, Amazon S3 provides a robust and scalable solution for handling static files and media in a Django project. It optimizes performance, simplifies deployment, and enhances the overall scalability of your application.</p>
<p> Many corporations and large enterprises use Amazon S3 in conjunction with Django and Nginx, especially for handling static files and media storage in their web applications. Amazon S3 is a highly scalable, durable, and cost-effective object storage service provided by Amazon Web Services (AWS). Its features and benefits make it an attractive choice for various use cases, including those in corporate environments.</p>
<p> I'm planning to craft a dedicated article on seamlessly integrating Amazon S3 with a Django project. Writing the details here might unintentionally extend this conversation.</p>
</li>
<li><p><strong>Optimizing Jenkins Security: Preventing Builds on the Built-In Node</strong><br /> Avoid executing any builds on the default built-in node by taking the following steps: Navigate to Manage Jenkins &gt; Manage Nodes and Clouds, choose Built-In Node from the list, select Configure from the menu, set the number of executors to 0, and save the configuration. Ensure that you establish clouds or build agents for executing builds; otherwise, build initiation will not be possible.</p>
<p> Why is this a crucial practice? By default, Jenkins is configured to execute builds on the built-in node for the sake of simplicity during initial setup. However, this approach is not recommended for the long term. Running builds on the built-in node grants them the same level of access to the controller file system as the Jenkins process. To mitigate security risks, it is highly recommended to abstain from running any builds on the built-in node and, instead, utilize agents (either statically configured or provided by clouds) to carry out builds.</p>
</li>
<li><p><strong>Remove unnecessary permissions:</strong><br /> Eliminate redundant permissions for the 'authenticated users' group by navigating to Manage Jenkins &gt; Configure Global Security &gt; Authorization &gt; Authenticated users. It is crucial to follow this step because, in alignment with the preceding section, even when employing a Matrix-based authorization method, it is imperative to prevent the default 'authenticated users' group from possessing unnecessary permissions. Whenever feasible, revoke any excessive permissions assigned to this default group and allocate permissions specifically to the groups or users that you have defined."</p>
</li>
<li><p><strong>Dockerize the Django Project</strong></p>
<p> Docker eliminates the "it works on my machine" problem by packaging your application and its dependencies into a single container. This reduces the likelihood of issues arising from differences in development and production environments.</p>
<ul>
<li><p>Use a Docker image with Python and install necessary dependencies for your Django application. Run Gunicorn as the application server inside the Docker container to serve your Django app.</p>
</li>
<li><p>Set up a separate Docker container with Nginx as the reverse proxy. Configure Nginx to forward requests to the Gunicorn server. This separation allows Nginx to handle static file serving efficiently.</p>
</li>
<li><p>By dockerizing your Django project and integrating it with Nginx, Gunicorn, and Jenkins, you establish a reliable and portable infrastructure that fosters consistency, scalability, and efficient collaboration throughout the development and deployment lifecycle.</p>
</li>
</ul>
</li>
<li><p><strong>Add the test - Continuous Integration</strong></p>
<p> Every project has some test suite to test the application, the build should be successful, only if all the tests are passing, so you can run the test suite and add it as a stage in Jenkins.</p>
<pre><code class="lang-bash"> python3 manage.py <span class="hljs-built_in">test</span>
</code></pre>
<p> Create a File like testrunner.sh</p>
<pre><code class="lang-bash"> <span class="hljs-comment">#!/bin/bash</span>

 <span class="hljs-built_in">cd</span> /var/lib/jenkins/workspace/django-cicd/

 <span class="hljs-built_in">source</span> env/bin/activate

 <span class="hljs-built_in">cd</span> your_project/
 python3 manage.py <span class="hljs-built_in">test</span>
</code></pre>
<p> Add it in the pipeline.</p>
<pre><code class="lang-bash"> pipeline {
     agent any
     stages {
         stage(<span class="hljs-string">'Setup Python Virtual ENV for dependencies'</span>) {
             steps {
                 sh <span class="hljs-string">''</span><span class="hljs-string">'
                 chmod +x envsetup.sh
                 ./envsetup.sh
                 '</span><span class="hljs-string">''</span>
             }
         }
         stage(<span class="hljs-string">'Test Suite'</span>) {
             steps {
                 sh <span class="hljs-string">''</span><span class="hljs-string">'
                 chmod +x testrunner.sh
                 ./testrunner.sh
                 '</span><span class="hljs-string">''</span>
             }
         }
         stage(<span class="hljs-string">'Setup Gunicorn Setup'</span>) {
             steps {
                 sh <span class="hljs-string">''</span><span class="hljs-string">'
                 chmod +x gunicorn.sh
                 ./gunicorn.sh
                 '</span><span class="hljs-string">''</span>
             }
         }
         stage(<span class="hljs-string">'Setup NGINX'</span>) {
             steps {
                 sh <span class="hljs-string">''</span><span class="hljs-string">'
                 chmod +x nginx.sh
                 ./nginx.sh
                 '</span><span class="hljs-string">''</span>
             }
         }
     }
 }
</code></pre>
<p> This Jenkins pipeline script has successfully outlined a streamlined workflow for your Django project. We started by setting up a Python virtual environment for dependencies, ran a comprehensive test suite to ensure code integrity, and seamlessly integrated Gunicorn and NGINX for production-ready deployment. Embracing Continuous Integration (CI) principles, the script automates the testing phase, ensuring that code changes are validated consistently. Additionally, when combined with other stages, it lays the foundation for a powerful Continuous Deployment (CD) pipeline, automating the delivery process up to the production environment. By implementing this Jenkins pipeline, you're not just coding; you're orchestrating a robust and efficient development lifecycle.</p>
</li>
</ol>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this guide, we've unlocked the power of Jenkins CI/CD for Django, seamlessly orchestrating builds, tests, and deployments on an EC2 instance. 🛠️ With Nginx as our reverse proxy and Gunicorn as the WSGI server, our Django projects now thrive in a secure and high-performance environment.</p>
<p>As you wrap up this journey, remember: Continuous improvement is the heartbeat of effective development. 🔄 Keep iterating, refining, and adapting your CI/CD pipeline to fuel the evolution of your Django projects.</p>
<p>Cheers to streamlined development, collaborative coding, and the endless possibilities that Jenkins unfolds! 🎉 Happy coding, and may your Django endeavors soar to new heights! 🚀</p>
<p><img src="https://t3.ftcdn.net/jpg/04/95/23/08/360_F_495230877_43nmQoL18cqDp4tsgXWL4t2U4HJ9xahc.jpg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Basics to Advance: Unleashing the Power of AWK in Advanced Linux Operations]]></title><description><![CDATA[Introduction
If you are a beginner or intermediate in using Linux, you must know some basic commands like cd, ls, sudo, rmdir etc. And I think these commands are ok but there is a powerful command which user might ignore or don't use due to its tough...]]></description><link>https://vishnutiwari.dev/basics-to-advance-unleashing-the-power-of-awk-in-advanced-linux-operations</link><guid isPermaLink="true">https://vishnutiwari.dev/basics-to-advance-unleashing-the-power-of-awk-in-advanced-linux-operations</guid><category><![CDATA[Linux]]></category><category><![CDATA[awk]]></category><category><![CDATA[grep]]></category><category><![CDATA[advanced linux]]></category><category><![CDATA[linux for beginners]]></category><category><![CDATA[linux for devops]]></category><category><![CDATA[linux-commands]]></category><category><![CDATA[research]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Sun, 07 Jan 2024 19:48:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704357900871/333aab91-c6fc-41c5-9cb9-3f36b3abfe82.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>If you are a beginner or intermediate in using Linux, you must know some basic commands like cd, ls, sudo, rmdir etc. And I think these commands are ok but there is a powerful command which user might ignore or don't use due to its toughness or unawareness</p>
<p>When it comes to command-line text processing in Linux, AWK stands out as a versatile and powerful tool. In this article, we'll take a closer look at a basic AWK command and explore its capabilities in extracting specific information from text files.</p>
<hr />
<h2 id="heading-scenarios">Scenarios</h2>
<p>Before you start learning any command or tool, it's important to understand how it can actually help you in real-life situations, especially in your daily tasks. If something seems fancy but doesn't have a practical use, it might not be worth learning.</p>
<p>Learning should be about gaining skills that make your everyday life easier and more efficient, tackling the challenges you face regularly. So, before diving in, consider whether what you're learning has a meaningful impact on your day-to-day activities.</p>
<p>So that's why am sharing some real use case or scenario where awk command could be really helpful.</p>
<ol>
<li><p><strong>Server Log Analysis:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Analyzing Apache web server or any web server logs to extract information about the number of requests for each page.</p>
<p>  Assuming you have an Apache log file named <code>access.log</code> with entries like</p>
<pre><code class="lang-plaintext">  192.168.0.1 - - [01/Jan/2022:12:00:00 +0000] "GET /page1 HTTP/1.1" 200 1234
  192.168.0.2 - - [01/Jan/2022:12:01:00 +0000] "GET /page2 HTTP/1.1" 404 5678
  192.168.0.3 - - [01/Jan/2022:12:02:00 +0000] "GET /page1 HTTP/1.1" 200 7890
</code></pre>
<p>  You can use the awk command to extract and count the number of requests for each page</p>
<p>  <strong>Output</strong></p>
<pre><code class="lang-plaintext">     2 /page1
     1 /page2
</code></pre>
</li>
</ul>
</li>
<li><p><strong>CSV File Manipulation:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Consider you have a CSV file named <code>data.csv</code> with the following content.</p>
<pre><code class="lang-plaintext">  Name,Age,Occupation
  Alice,28,Engineer
  Bob,35,Developer
  Charlie,22,Student
  David,40,Manager
</code></pre>
<p>  Now, let's say you want to extract and display only the "Name" and "Occupation" columns. You can use the following AWK command:</p>
<p>  <strong>Output</strong></p>
</li>
<li><pre><code class="lang-plaintext">            Name Occupation
            Alice Engineer
            Bob Developer
            Charlie Student
            David Manager
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Password File Analysis:</strong></p>
<ul>
<li><strong>Scenario:</strong> Extracting and displaying user information from the <code>/etc/passwd</code> file.</li>
</ul>
</li>
<li><p><strong>Network Configuration Review:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Analyzing the output of the <code>ifconfig</code> command to display network interface details.</p>
<p>  For e.g. ifconfig commands give you this output.</p>
<pre><code class="lang-plaintext">  eth0: flags=4163&lt;UP,BROADCAST,RUNNING,MULTICAST&gt;  mtu 1500
          inet 192.168.0.2  netmask 255.255.255.0  broadcast 192.168.0.255
          inet6 fe80::a00:27ff:fe8a:e2ab  prefixlen 64  scopeid 0x20&lt;link&gt;
          ether 08:00:27:8a:e2:ab  txqueuelen 1000  (Ethernet)
          RX packets 1501  bytes 1666445 (1.6 MB)
          RX errors 0  dropped 0  overruns 0  frame 0
          TX packets 1275  bytes 96476 (96.4 KB)
          TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

  lo: flags=73&lt;UP,LOOPBACK,RUNNING&gt;  mtu 65536
          inet 127.0.0.1  netmask 255.0.0.0
          inet6 ::1  prefixlen 128  scopeid 0x10&lt;host&gt;
          loop  txqueuelen 1000  (Local Loopback)
          RX packets 9  bytes 546 (546.0 B)
          RX errors 0  dropped 0  overruns 0  frame 0
          TX packets 9  bytes 546 (546.0 B)
          TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
</code></pre>
<p>  By using awk command, you can extract and display network interface details.</p>
<p>  <strong>Output</strong></p>
<pre><code class="lang-plaintext">  Interface: eth0 IP Address: 192.168.0.2
  Interface: lo IP Address: 127.0.0.1
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Custom Log Parsing:</strong></p>
</li>
</ol>
<ul>
<li><p><strong>Scenario:</strong> Parsing a custom log format to extract relevant information.</p>
<p>  Let's consider a custom log file named <code>custom.log</code> with entries like:</p>
<pre><code class="lang-plaintext">  2022-01-01T12:00:00+00:00 | User=John | Action=Login | Status=Success
  2022-01-01T12:15:00+00:00 | User=Alice | Action=Logout | Status=Success
  2022-01-01T12:30:00+00:00 | User=Bob | Action=Login | Status=Failure
</code></pre>
<p>  Assuming you want to extract and display the date, user, action, and status information, by using awk you can get the output like this</p>
<p>  <strong>Output</strong></p>
<pre><code class="lang-plaintext">  Date: 2022-01-01T12:00:00+00:00 User: John Action: Login Status: Success
  Date: 2022-01-01T12:15:00+00:00 User: Alice Action: Logout Status: Success
  Date: 2022-01-01T12:30:00+00:00 User: Bob Action: Login Status: Failure
</code></pre>
</li>
</ul>
<p>These examples demonstrate how AWK can be applied in various real-world scenarios for data extraction, processing, and analysis in a Linux or Unix environment. The flexibility and power of AWK make it a valuable tool for system administrators, developers, and data analysts.</p>
<p>There are numerous use cases where you can use AWK command efficiently without much writing. I believe now we are good to go for learning this thing.</p>
<hr />
<h2 id="heading-what-is-awk">What is AWK?</h2>
<p>Awk is a command line utility or program or scripting language or text processing utility that means you give it some text and it can grab certain columns, certain rows, certain fields from the text for you. You can tell it to go search for certain string, patterns in the text and even replace those string patterns with other strings. Its a really powerful program and that's why developers and engineer mostly use all the time.</p>
<details><summary>What is utility?</summary><div data-type="detailsContent">A "utility" refers to a software tool or program designed to perform a specific task or set of tasks, often related to system management, data processing, or other essential functions. Utilities are typically command-line or graphical applications that assist users in performing various operations on a computer.</div></details>

<blockquote>
<p>"As a developer working in big tech companies, i probably overused awk. I used awk everywhere especially in my shell scripting because I'm really comfortable with it and it's one of those programs that once you learn awk, you wonder why you didn't learn it sooner because it's such a powerful program. " by Vishnu Tiwari</p>
</blockquote>
<p>AWK is particularly well-suited for text processing and is commonly used in Unix and Unix-like operating systems for tasks such as data extraction, reporting, and text pattern matching. Being a command-line utility, it allows users to efficiently perform these tasks by executing commands in a terminal environment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704366123720/f743b267-d275-45d0-acbb-f99cf6f344f0.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-basics-syntax-examples">Basics - Syntax + Examples</h2>
<p>Hey, let's head it to the basics and explore the awk command for printing the columns, to use input and output field separator.</p>
<h3 id="heading-syntax">Syntax</h3>
<pre><code class="lang-bash">awk options <span class="hljs-string">'selection _criteria {action }'</span> input-file &gt; output-file
</code></pre>
<p>Examples</p>
<pre><code class="lang-bash">ps
</code></pre>
<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704367630943/8bdd23ad-278e-45de-865a-9d9daacd770b.png" alt /></p>
<pre><code class="lang-bash">ps | awk <span class="hljs-string">'{print $1}'</span>
</code></pre>
<details><summary>ps command</summary><div data-type="detailsContent">The <code>ps</code> command in Linux is used to provide information about currently running processes on a system.</div></details>

<p><strong>print $1</strong> - print the first column , change col no by putting the no. after $. like $2 for second column.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704367975316/c664f893-aae2-4496-9de7-cc75e5f9439e.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash">ps | awk <span class="hljs-string">'{print $0}'</span>
</code></pre>
<p><strong>$0</strong> - simply prints everything just like cat</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">{print} - also prints the all, just like {print $0}</div>
</div>

<p><strong>Output</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704368285379/7547afc8-9471-4638-b2f7-d7c8d24d88fb.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704368365155/d6b5c6ab-3ab7-40d1-b485-448ddcbefa82.png" alt /></p>
<p>So one of the files that people love to use awk on GNU/Linux system is the /etc/passwd file, that is a file that lists all the users on your Linux system</p>
<pre><code class="lang-bash">cat /etc/passwd
</code></pre>
<p>the output looks like this,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704369155344/43d94e37-fa46-43ee-9c91-d7ec3d6c5369.png" alt class="image--center mx-auto" /></p>
<p>there's not a lot of spaces to it, there are columns i mean it is separated into columns but the columns they are separated by colons here.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Note : AWK treats spaces as the column delineator</div>
</div>

<p>so for printing all the users!</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">":"</span> <span class="hljs-string">'{print $1}'</span> /etc/passwd
</code></pre>
<p><strong>-F</strong> : for providing field separator, by default awk uses spaces as field, it basically splits the column by ':'.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704370073074/23df3ba5-99e0-4623-8372-1a3858c44810.png" alt class="image--center mx-auto" /></p>
<p>if you want to print multiple columns, add the column no.</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">":"</span> <span class="hljs-string">'{print $1 $6 $7}'</span> /etc/passwd
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704370903191/2c147483-5ceb-43e6-a61e-57e083cdd62c.png" alt class="image--center mx-auto" /></p>
<p>its not very readable because we didn't tell it to separate the columns with spaces or colons or anything. We told it, hey print 1,6 and 7 column.</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">":"</span> <span class="hljs-string">'{print $1 "\t" $6 "\t" $7}'</span> /etc/passwd
</code></pre>
<details><summary>\t</summary><div data-type="detailsContent">used for giving a proper tab space</div></details>

<p>![](https://cdn.hashnode.com/res/hashnode/image/upload/v1704533913460/70aba778-05c4-43f4-b8b7-858075ed178e.png align="left")</p>
<p>In the output, we can see its showing tab spaces after all column and it's much more readable that way.</p>
<p>Now other than specifying a field separator to search for and use you know to determine what the columns are, you can actually print out the field separator as well and you can tell it to change the field separator to a different character as part of the output. you can do all this by using this command.</p>
<pre><code class="lang-bash">awk <span class="hljs-string">'BEGIN{FS=":"; OFS="-"} {print $1, $6, $7}'</span> /etc/passwd
</code></pre>
<p><code>BEGIN{FS=":"; OFS="-"}</code>: This part of the command is executed before processing any input lines. It sets the input field separator (FS) to a colon (<code>:</code>) and the output field separator (OFS) to a dash (<code>-</code>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704534721862/a662db71-d646-40a3-9147-65c57ed3ed62.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-intermediate-awk-for-daily-official-use">Intermediate - AWK for Daily + Official Use</h2>
<p><strong>In this level, we going to upgrade a one level up from the basics and learn about patterns</strong></p>
<ul>
<li>if you want to get the last column, you can use $NF for printing the last column , for example , you want to print all the shells present in your machine</li>
</ul>
<pre><code class="lang-bash">cat /etc/shells
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704542068518/effd06ae-c81d-43d2-8c38-eeb551a2e086.png" alt class="image--center mx-auto" /></p>
<p>As you can see in the output, the first line is a comment, which is not a valid shell. Therefore, we only need the lines that start with a forward slash '/'. To achieve this, we can use a command like the one provided.</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">'/'</span> <span class="hljs-string">'/^\// {print $NF}'</span> /etc/shells
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704543347110/ecb39f9a-c4b0-4a86-9bec-e41387ac4f42.png" alt class="image--center mx-auto" /></p>
<p><strong>//</strong> - Anything inside these two forward slashes (//) will be used by AWK to search for patterns.</p>
<p><strong>^</strong> - it is the anchor, used to Indicates the beginning of the line</p>
<p><strong>\/</strong> - uses a backslash to tell AWK that the next character, a forward slash, is not a closing slash.</p>
<p>But in the output, you can see duplicate entries, which don't look good. We can use '<strong>uniq</strong>' to specify that we don't need duplicates.</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">'/'</span> <span class="hljs-string">'/^\// {print $NF}'</span> /etc/shells | uniq
</code></pre>
<p>for sorting</p>
<pre><code class="lang-bash">awk -F <span class="hljs-string">'/'</span> <span class="hljs-string">'/^\// {print $NF}'</span> /etc/shells | uniq | sort
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704544912076/4537a35b-5747-4be2-8736-66561608ed32.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704545845640/b611be49-6a0d-4059-874f-a966d0c5a8a1.png" alt class="image--center mx-auto" /></p>
<p>And let's run the 'df' command because it is another common command that provides nice columned information, and people often enjoy using AWK on its output</p>
<pre><code class="lang-bash">df
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704546383167/2a238d5a-8d85-4a40-a899-3994baa06184.png" alt class="image--center mx-auto" /></p>
<p>for printing the only <strong>tmpfs</strong> system,</p>
<pre><code class="lang-bash">df | awk <span class="hljs-string">'/^tmpfs/'</span>
</code></pre>
<p>You can also perform operations in the columns like addition, multiplication, division etc.</p>
<pre><code class="lang-bash">df | awk <span class="hljs-string">'/^tmpfs/ {print $1 "\t" $2 + $3}'</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704547455129/169e7df0-ae74-4d7a-aefa-4a45634d39ee.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704547932473/296180fe-37e2-42bf-a8d7-e0cd407e85ea.png" alt class="image--center mx-auto" /></p>
<p>You can also perform operations based on certain conditions</p>
<pre><code class="lang-bash">cat /etc/shells
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558049200/f8592e5a-9782-4dc9-aa00-f68381bd6dda.png" alt /></p>
<p>For printing a line less than 8 characters</p>
<pre><code class="lang-bash">awk <span class="hljs-string">'length($0) &lt; 8'</span> /etc/shells
</code></pre>
<p>for printing shell less than 5 character</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704558915055/7c302ec8-a86f-4e2f-9292-25c24e913db1.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704559034542/f2eb8612-d4f5-430a-87af-770f4ab98679.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-advance-awk-for-pro-developers">Advance - AWK For Pro Developers</h2>
<p><strong>In this level, we going to upgrade a one more level up from the intermediate and learn about if/else, loops etc.</strong></p>
<h3 id="heading-if-else-in-awk">if / else in awk</h3>
<p><strong>Syntax</strong></p>
<pre><code class="lang-bash">awk <span class="hljs-string">'{
    if (condition) {
        print $1 ";
    } else {
        print $2;
    }
}'</span> input_file
</code></pre>
<p><strong>Example</strong></p>
<pre><code class="lang-bash">ps -ef <span class="hljs-comment"># For printing all the process in your system</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704646432987/681aaa2c-8db1-4ce8-95ba-f53c1d233917.png" alt class="image--center mx-auto" /></p>
<p>now we can check if the process is kworker . for printing all the kworker process, we can do</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Note: For checking patterns inside if/else use '~' instead of '=='.</div>
</div>

<pre><code class="lang-bash">ps -ef | awk <span class="hljs-string">'{if ($NF~ /kworker/) print $0}'</span>
</code></pre>
<p>Now we can also distinguish that which is a kworker process or which one is regular by using else.</p>
<pre><code class="lang-bash">ps -ef | awk <span class="hljs-string">'{if ($NF~ /kworker/){ print $NF "\t kworker process"} else {print $NF "\t regular process"}}'</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704647275721/fc469b1c-ed3a-447b-b63f-01bc78f40989.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704647312572/ac4f220c-9ef0-4531-b6a3-8412b5888df3.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-for-loop">For loop</h3>
<p>Since, awk is an scripting language we can also use loops, In AWK, there are two main types of loops: the <code>for</code> loop and the <code>while</code> loop.</p>
<pre><code class="lang-bash">awk <span class="hljs-string">'{
    for (i = 1; i &lt;= 5; i++) {
        print "Number:", i;
    }
}'</span> input_file
</code></pre>
<p>If you use this syntax, you need to mandatorily pass a input file, it basically run the loop for each line</p>
<p>for just performing the operations without passing the input file, you can use BEGIN.</p>
<pre><code class="lang-bash">ifconfig | awk <span class="hljs-string">'/^[a-zA-Z]/{interface=$1; next} /inet addr:/{print "Interface:", interface, "IP:", $2}'</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704650276801/a5af6b98-1d6b-4fdc-86b8-a9a19fc4c06a.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-while-loop">while loop</h3>
<p>In AWK, you can use a <code>while</code> loop to repeatedly execute a block of code as long as a certain condition is true. Here's a simple example of using a <code>while</code> loop in AWK</p>
<pre><code class="lang-bash">awk <span class="hljs-string">'{
    i = 1;
    while (i &lt;= 5) {
        print "Number:", i;
        i++;
    }
}'</span> input_file
</code></pre>
<p>In this example:</p>
<ul>
<li><p><code>i = 1</code>: Initialization of the loop variable <code>i</code> to 1.</p>
</li>
<li><p><code>while (i &lt;= 5)</code>: The condition for the loop to continue as long as <code>i</code> is less than or equal to 5.</p>
</li>
<li><p><code>print "Number:", i</code>: Code inside the loop that prints the current value of <code>i</code>.</p>
</li>
<li><p><code>i++</code>: Incrementing <code>i</code> by 1 in each iteration.</p>
</li>
</ul>
<h3 id="heading-else-if">else if</h3>
<p>! In AWK, you can use <code>if</code> and <code>else if</code> statements to implement conditional logic. Here's an example:</p>
<pre><code class="lang-bash">awk <span class="hljs-string">'{
    if ($1 &gt; 10) {
        print $1 " is greater than 10";
    } else if ($1 == 10) {
        print $1 " is equal to 10";
    } else {
        print $1 " is less than 10";
    }
}'</span> input_file
</code></pre>
<p>In this example, the AWK script reads input from <code>input_file</code> (you can replace it with your actual file name), and for each line, it checks the value in the first column (<code>$1</code>). Depending on the value, it prints a different message.</p>
<p>Explanation:</p>
<ul>
<li><p><code>if ($1 &gt; 10)</code>: If the value in the first column is greater than 10, execute the corresponding block of code.</p>
</li>
<li><p><code>else if ($1 == 10)</code>: If the value is equal to 10, execute this block of code.</p>
</li>
<li><p><code>else</code>: If none of the above conditions are true, execute this block.</p>
</li>
</ul>
<p>You can adjust the conditions and actions inside the blocks to suit your specific requirements.</p>
<h2 id="heading-some-common-useful-commands-for-daily-use">Some Common Useful Commands For Daily Use</h2>
<ol>
<li><p><strong>substr</strong></p>
<p> The <code>substr</code> function in AWK is used to extract a portion of a string. Its basic syntax is:</p>
<pre><code class="lang-bash"> substr(string, start[, length])
</code></pre>
<ul>
<li><p><code>string</code>: The input string from which you want to extract a substring.</p>
</li>
<li><p><code>start</code>: The position in the string where extraction begins. The position is 1-based.</p>
</li>
<li><p><code>length</code> (optional): The number of characters to extract. If omitted, it extracts the substring from the start position to the end of the string.</p>
</li>
</ul>
</li>
</ol>
<p>    for example , you have a file and you want to use substr on it, the actual use is depend on the layout of the file , but for demo see this example</p>
<pre><code class="lang-bash">    awk <span class="hljs-string">'{print substr($0, 3)}'</span> numbered.txt
</code></pre>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704652837605/adb3193c-c0ba-4635-a89b-0780de5f4a6d.png" alt /></p>
<ol>
<li><p><strong>match, RSTART and RLENGTH</strong></p>
<p> In AWK, the <code>match</code> function is used to search a string for a specified pattern and sets the values of <code>RSTART</code> and <code>RLENGTH</code> to the starting position and length of the matched substring, respectively. The basic syntax of <code>match</code> is as follows:</p>
<pre><code class="lang-bash"> match(string, regexp)
</code></pre>
<ul>
<li><p><code>string</code>: The input string where you want to search for the pattern.</p>
</li>
<li><p><code>regexp</code>: The regular expression pattern to search for in the string.</p>
</li>
</ul>
</li>
</ol>
<p>    Here's an example:</p>
<pre><code class="lang-bash">    awk <span class="hljs-string">'match($0,/o/) {print $0, "Has O character at index", RSTART, "with length", RLENGTH}'</span> numbered.txt
</code></pre>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704654255200/746a47ef-e056-4c50-a228-89139afa4015.png" alt class="image--center mx-auto" /></p>
<ol>
<li><p><strong>NR</strong><br /> In AWK, <code>NR</code> is a built-in variable that represents the current record (line) number being processed. It is automatically incremented by AWK as it reads each input line. <code>NR</code> is especially useful when you want to perform actions based on the line number.</p>
<pre><code class="lang-bash"> df | awk <span class="hljs-string">'NR==6, NR==8 {print NR".", $0}'</span>
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704654544897/9e6c5ead-7acc-4924-a138-2708420e5480.png" alt class="image--center mx-auto" /></p>
<p> <strong>for checking the line count of any file!</strong></p>
<pre><code class="lang-bash"> df | awk <span class="hljs-string">'END {print NR}'</span>
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704654997405/2dbc832a-21bc-4779-a280-27070c318f9a.png" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>For checking IP Addresses</strong><br /> Using <code>ifconfig</code> with AWK can be useful for parsing and extracting specific information about network interfaces. <code>ifconfig</code> provides details about the network configuration on a system, and AWK can help filter and format this information according to your needs.</p>
<pre><code class="lang-bash"> ifconfig | awk  <span class="hljs-string">'/^[a-zA-Z]/ {print "Interface: " $1 } /inet/ {print "IP Addrress:" $2}'</span>
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1704655184642/51e88a05-f9ba-42bc-b56b-af76631a5997.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, our exploration of AWK has provided a comprehensive understanding of this powerful text processing tool. From its fundamental syntax to advanced features, we've delved into the intricacies that make AWK a versatile and indispensable asset in the realm of data manipulation and analysis.</p>
<p>Throughout the article, we've uncovered how AWK can be applied in various real-world scenarios, demonstrating its utility in tasks ranging from simple text processing to more complex data transformations. The practical examples and use cases serve as a guide for both beginners and experienced users, showcasing the flexibility and efficiency of AWK in handling diverse text-based challenges.</p>
<p>As we bring this AWK journey to a close, I extend my gratitude for your dedication in navigating through the intricacies of this scripting language. The knowledge gained here lays the foundation for enhanced productivity and problem-solving capabilities. Whether you're a newcomer or a seasoned AWK enthusiast, may the skills acquired pave the way for seamless text processing endeavors.</p>
<p><img src="https://media1.giphy.com/media/vxNCVEe0PI9A3YVJEX/giphy.gif" alt class="image--center mx-auto" /></p>
<p>That's a wrap on this article, where we journeyed from AWK basics to advanced ninja moves and explored its everyday applications. Kudos for sticking with it till the end! Much love and catch you at the next article. Stay sharp and keep rocking that tech game! ✌️</p>
<p>Thank you again for your time and commitment. Here's to harnessing the full potential of AWK in your future endeavors. Until our paths cross again in the realm of knowledge exploration, stay curious and keep scripting!</p>
<p><img src="https://i.pinimg.com/originals/0b/fa/6c/0bfa6c0be319f1af0b1f802a4f78842d.gif" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Mastering Data Transfer: A Django Developer's Guide to Database Migration]]></title><description><![CDATA[Overview
The Django Data Migration Tutorial is a step-by-step guide to seamlessly transfer data between databases and deploy your Django application to different environments without losing critical data. This tutorial focuses on flexibility, allowin...]]></description><link>https://vishnutiwari.dev/mastering-data-transfer-a-django-developers-guide-to-database-migration</link><guid isPermaLink="true">https://vishnutiwari.dev/mastering-data-transfer-a-django-developers-guide-to-database-migration</guid><category><![CDATA[django database transfer]]></category><category><![CDATA[django-developer]]></category><category><![CDATA[Django]]></category><category><![CDATA[databasemigration]]></category><category><![CDATA[SQLite]]></category><category><![CDATA[django rest framework]]></category><category><![CDATA[django orm]]></category><dc:creator><![CDATA[Vishnu Tiwari]]></dc:creator><pubDate>Fri, 29 Dec 2023 11:32:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/BI465ksrlWs/upload/037200994b11ae79d2060bcca48a3c86.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-overview">Overview</h2>
<p>The Django Data Migration Tutorial is a step-by-step guide to seamlessly transfer data between databases and deploy your Django application to different environments without losing critical data. This tutorial focuses on flexibility, allowing users to switch between different database backends such as SQLite, MySQL, or any other supported by Django.</p>
<blockquote>
<p>This article provides a comprehensive tutorial on Django Data Migration, guiding you through the process of transferring data between databases and deploying Django applications without data loss. It emphasizes flexibility, enabling users to work with various database backends like SQLite and MySQL</p>
</blockquote>
<hr />
<h3 id="heading-key-features">Key-Features</h3>
<ul>
<li><p><strong>Database Switching:</strong> Easily switch between different database backends without data loss.</p>
</li>
<li><p><strong>Step-by-Step Guide:</strong> Follow a comprehensive guide to migrate data smoothly.</p>
</li>
<li><p><strong>Compatibility:</strong> Applicable to various databases supported by Django.</p>
</li>
<li><p><strong>Deployment Readiness:</strong> Ensure your application is ready for deployment in different environments.</p>
</li>
</ul>
<hr />
<h3 id="heading-personal-experience">Personal Experience</h3>
<p>Throughout my tenure as a backend developer at IBM Corp, I encountered a situation where we populated our development database (PostgreSQL - version 14) with numerous records and users with diverse user types.</p>
<p>When it came to configuring the QA environment for both manual and automation testing, the testing teams expressed the need for a substantial amount of data to facilitate their testing and comprehension processes.</p>
<p>Recognizing the potential time constraints and inefficiencies associated with manual data input, I did some research and sought guidance from experienced colleagues, I successfully conducted a data migration from the development database to the test database, excluding specific tables. In this article, I will share the insights gained from this experience, providing a guide on how to seamlessly transfer data between databases.</p>
<hr />
<h2 id="heading-transferring-data-to-another-db-in-a-django-application">Transferring Data to another DB in a Django Application</h2>
<p>Helps In Switch to another Deploying Env. without Losing Data</p>
<p><img src="https://camo.githubusercontent.com/b771cfc729b59bfe6ff4e4219965e8e32dda8838b13ec3648dee57eec4a6b305/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f63734b694144344833347137675f724a4b646849712e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<hr />
<h3 id="heading-step-1-generating-a-json-file-which-includes-your-db-content">Step 1: Generating a JSON file which includes your DB content</h3>
<p>Imagine your app is a treasure chest, and your data is the treasure. To capture all that valuable info, there's a superhero command: <code>python</code> <a target="_blank" href="http://manage.py"><code>manage.py</code></a> <code>dumpdata &gt; data.json</code>. This command works like a camera, snapping a pic of your entire database and saving it in a file called "data.json." No need to worry about how complex your app is – this command is your data snapshot wizard.</p>
<p><em>Run this command on your terminal or cmd</em></p>
<pre><code class="lang-powershell">python manage.py dumpdata &gt; data.json
</code></pre>
<p><strong>Note:</strong> For excluding any models use "<strong><em>--exclude</em></strong>"</p>
<pre><code class="lang-powershell">python manage.py dumpdata -<span class="hljs-literal">-exclude</span> auth.permission -<span class="hljs-literal">-exclude</span> contenttypes &gt; data.json
</code></pre>
<hr />
<h3 id="heading-step-2-add-your-new-database-to-the-settings">Step 2: Add your new database to the settings.</h3>
<p>Add the new database to your <a target="_blank" href="http://settings.py"><strong>settings.py</strong></a> file like this and run all your migrations for creating the table structure and DB schema.</p>
<p><img src="https://camo.githubusercontent.com/3716e13ee0935e17f360c96eecf83f386f3b27f5e13de986033a914f6395597d/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f734b50327a304e41524243774639424f375244556f2e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<p>Note: Don't hardcode the details of your db instead create a .env file(add this file to .gitignore)</p>
<p><em>Make the migrations now, use the default command for migration if u removed the old DB and named it 'default'.</em></p>
<p><strong>Run the migrations</strong></p>
<pre><code class="lang-powershell">python manage.py migrate -<span class="hljs-literal">-database</span>=new
</code></pre>
<p><img src="https://camo.githubusercontent.com/dd3d9ca6ffb961c342c07d978f097d934a92eb86316d5900111632b074e30c28/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f53496a4e6f6b78394a7a71326f42365830667333432e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-convert-the-datajson-to-utf-8-and-load-your-data-into-new-db">Step 3: Convert the data.json to UTF-8 and Load your data into new db</h3>
<p>Your data.json is of UTF-16LE and you need to convert it into UTF-8 and than load your data to new database.</p>
<p>You can change it online or while saving as select the file type to UTF-8.</p>
<p><img src="https://camo.githubusercontent.com/0ffbd0a50ae5cb48fa3f57be5971e5966fb376a3b8c36f2edcda7aba95744a80/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f6f5934454a67657437757479644b696b46465742482e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<pre><code class="lang-powershell"> python manage.py loaddata data.json -<span class="hljs-literal">-database</span>=new
</code></pre>
<p><img src="https://camo.githubusercontent.com/d332bf1c7549639f4baf306dd9f9f5da86f7c9acb7bdce684cd76d4de4a0f1c0/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f6a794d4c7a77546e6c7075383079326736394a34762e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-4-all-data-is-succesfully-transferred-to-new-db">Step 4: All data is succesfully transferred to new DB</h3>
<p>This process is useful for creating backups, migrating data between databases, or sharing sample data with others working on the project. Keep in mind that the <code>**dumpdata**</code> and <code>**loaddata**</code> commands are part of Django's serialization framework, and they work with various serialization formats, not just JSON.</p>
<p><img src="https://camo.githubusercontent.com/080fa2717b54420f101d74031eb75f84c44c81874a9b45ef478f714e958baee8/68747470733a2f2f6572617365722e696d6769782e6e65742f776f726b7370616365732f756e6c4341447767487a754b314e5576327644672f50794947593653334c4b597550744c5369764643466c65585a6278322f4d7033335670572d426e666b4b4c46645678316a742e706e673f69786c69623d6a732d332e372e30" alt class="image--center mx-auto" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, the process of migrating data from one database to another in Django emerges as a pivotal skill for developers seeking efficiency and seamlessness in their projects.</p>
<p>As we close this chapter, armed with the knowledge of how to navigate database migrations, developers can confidently ensure data continuity across various stages of their application's lifecycle. Here's to smooth migrations and the continued evolution of robust, data-driven Django applications!</p>
<p><img src="https://media.istockphoto.com/id/1225505894/vector/goodbye-colorful-typography-banner.jpg?s=612x612&amp;w=0&amp;k=20&amp;c=zJ5ubCRtB6T0pihto6yrTl-Bsmy865D-WwHGvGtQ3CE=" alt class="image--center mx-auto" /></p>
]]></content:encoded></item></channel></rss>