<?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[Saurav Jalui]]></title><description><![CDATA[Backend Software Engineer using Django and Node.
#### I talk about:
1. Software Engineering.
2. Web development.
3. Clean Code and Design Patterns in Python and]]></description><link>https://sauravjalui.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 12:37:14 GMT</lastBuildDate><atom:link href="https://sauravjalui.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Creating Python APIs - The Django REST framework. Basic authentication[14/n]]]></title><description><![CDATA[Welcome back to my series on creating Python APIs using Django REST framework.
Today we will view basic authentication in our API. 
So far we've been using the API after signing into the website but what if someone wants to access the API via a mobil...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-basic-authentication14n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-basic-authentication14n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 03 Dec 2020 18:14:19 GMT</pubDate><content:encoded><![CDATA[<h4 id="welcome-back-to-my-series-on-creating-python-apis-using-django-rest-framework">Welcome back to my series on creating Python APIs using Django REST framework.</h4>
<p>Today we will view basic authentication in our API. </p>
<p>So far we've been using the API after signing into the website but what if someone wants to access the API via a mobile device or using the <strong>curl </strong> command.</p>
<p>Let us try to use the <strong>curl</strong> command on the APIs current todos page (http://127.0.0.1:8000/api/todos/).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1607017114960/MITl6sETd.png" alt="image.png" /></p>
<p>The command to use is <code>curl http://127.0.0.1:8000/api/todos/</code></p>
<p>You should see something like the below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1607017300569/T3o-Inawd.png" alt="image.png" /></p>
<p>It basically says that we are not authenticated to be able to view todo objects, which is great security because we don't want other users to be able to view todo objects of other users.</p>
<p>You could use basic authentication passing the username and password as string with the url as follows:</p>
<p><code>curl http://127.0.0.1:8000/api/todos/ -u 'saurav:abc123'</code></p>
<p>However, if we try to access the todo objects we would have to pass it as json in our api which is a very tedious process.</p>
<p>In the next article we will talk about allowing the user to sign up via our API.</p>
<ul>
<li>You can view the entire code on my <a target="_blank" href="https://github.com/SauravJalui/To-Do">github</a> profile. </li>
</ul>
<p><strong> Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on  <a target="_blank" href="https://www.twitter.com/JaluiSaurav">Twitter </a> on my coding journey. </strong></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Completing todos using API [13/n]]]></title><description><![CDATA[Welcome back to my series on creating Python APIs using Django REST framework.
Today we will add the ability to be able to complete the todos using the API.
So first we start by creating an url for the completed todos page.

so the final url should l...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-completing-todos-using-api-13n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-completing-todos-using-api-13n</guid><category><![CDATA[Django]]></category><category><![CDATA[Web API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[REST API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 30 Nov 2020 17:26:12 GMT</pubDate><content:encoded><![CDATA[<h4 id="welcome-back-to-my-series-on-creating-python-apis-using-django-rest-framework">Welcome back to my series on creating Python APIs using Django REST framework.</h4>
<p>Today we will add the ability to be able to complete the todos using the API.</p>
<p>So first we start by creating an url for the completed todos page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606755328479/vAyUrl6qk.png" alt="image.png" /></p>
<p>so the final url should look like <strong>http://127.0.0.1:8000/api/todos/5/complete</strong></p>
<p>Now lets add its respective view as well:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606755581567/ljvm924xH.png" alt="image.png" /></p>
<p>Notice that we create a new <em>serializer</em> <strong>TodoCompleteSerializer</strong> for this, which we will create after we are done with the views:</p>
<p>Also notice that we have created a new function called <strong>perform_update</strong>, what it does is puts the datecompleted as the time now, so you have to import timezone from django utils using the command 
<code>from django.utils import timezone</code></p>
<p>Note that we already have datecompleted in our database so we just use its instance.</p>
<p>Now that we are done with our views, lets create that serializer we were talking about earlier; <strong>TodoCompleteSerializer</strong></p>
<h3 id="why-do-we-need-a-new-serializer">Why do we need a new serializer?</h3>
<p>It's because we want all of the fields to be read-only fields except the id which we will still include in the fields.</p>
<p>And since we want clean code its better to create two separate functions for two separate functions.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606755711159/8LCuBVVdp.png" alt="image.png" /></p>
<p>Don't forget to import this serializer using the command <code>from .serializers import TodoCompleteSerializer</code> in your views.py file.</p>
<p>Once all of this is done, we can go to the link:</p>
<p>http://127.0.0.1:8000/api/todos/5/complete</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606755296147/DfPllH1yC.png" alt="image.png" /></p>
<p>Notice the ids, although there are 2 todos left, there ids would not necessarily be 1 and 2, so make sure you check the id before entering it in the url.</p>
<p>You should see the following page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606756549896/k0gJNBkZM.png" alt="image.png" /></p>
<p>The great thing about Django REST Framework is that it tells you exactly what needs to be done.</p>
<p>In this specific case, it says <strong><em> "detail": "Method \"GET\" not allowed."</em></strong> and only <strong><em> PUT, PATCH, OPTIONS</em></strong> is allowed. This means that <em>GET</em> is not allowed and we would have to use <em>PUT</em>. So just click on the <em>PUT</em> button at bottom right.</p>
<p>You should see the below which means it went through.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606756742368/BKxh_Fm6l.png" alt="image.png" /></p>
<p>You can check that by going to the API main page (http://127.0.0.1:8000/api/todos/) where it lists all current todos.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606756793969/eIbsg2j7T.png" alt="image.png" /></p>
<p>and the #### completed todos:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606757002243/liHeWBfl-.png" alt="image.png" /></p>
<p>This is what you would see if you go through the app:</p>
<h4 id="current-todos">Current Todos</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606756866096/wijzvE0zo.png" alt="image.png" /></p>
<h4 id="completed-todos">Completed Todos</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606756903264/w53dm6qMD.png" alt="image.png" /></p>
<p>Congratulations! You just added a function to complete the todos using the APIs. Great Job!</p>
<p>Next we will see how to add basic authentication in our app.</p>
<ul>
<li>You can view the entire code on my <a target="_blank" href="https://github.com/SauravJalui/To-Do">github</a> profile. </li>
</ul>
<p><strong> Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on  <a target="_blank" href="https://www.twitter.com/JaluiSaurav">Twitter </a> on my coding journey. </strong></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. CRUD operations using API [12/n]]]></title><description><![CDATA[Welcome back to my series on creating Python APIs using Django REST framework.
Today we will add the basic functionality of CRUD (Create, Read, Update, Delete) in our API view.
First, let's add the option to create new todo using API.
For that we nee...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-crud-operations-using-api-12n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-crud-operations-using-api-12n</guid><category><![CDATA[Django]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Web API]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 26 Nov 2020 18:09:05 GMT</pubDate><content:encoded><![CDATA[<p>Welcome back to my series on creating Python APIs using Django REST framework.</p>
<p>Today we will add the basic functionality of CRUD (Create, Read, Update, Delete) in our API view.</p>
<p>First, let's add the option to create new todo using API.</p>
<p>For that we need to add the new url to the urls.py file of api folder.</p>
<p>Follow along with me as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606411791401/bW0NDAJrh.png" alt="image.png" /></p>
<p>Add the following to the views.py file. </p>
<p>Notice we use the same class as class TodoCompletedList. Instead of using the <strong>ListAPIView</strong> from generics we use the <strong>ListCreateAPIView</strong> because we want to create a todo using the api.</p>
<p>We make sure we use the <strong>TodoSerializer</strong> and permission class is to be authenticated because we want to make sure only authorized users have the ability to create todos.</p>
<p>We also define a create function to make sure it saves the todo under the user that is logged in. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606411826712/cjzJ2Ydh4.png" alt="image.png" /></p>
<p>The following is what you would see when you run the server and visit the link http://127.0.0.1:8000/api/todos/</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606411756893/Cf220LJOF.png" alt="Screenshot_2020-11-26 Todo List Create – Django REST framework(2).png" /></p>
<p>You can add a todo using the tabs below in the window.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606413829791/cjHyuGTqZ.png" alt="todo.png" /></p>
<p>You'd be able to see all the todos if you use the link http://127.0.0.1:8000/api/todos/</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606413901098/QUAscPwwW.png" alt="create.png" /></p>
<p>If you would go to the main app, you would be able to see the todo that you added using the api.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606413938649/kjv-IvduH.png" alt="image.png" /></p>
<p>In the next article, we will see how we can use the api to complete the todos.</p>
<ul>
<li>You can view the entire code on my <a target="_blank" href="https://github.com/SauravJalui/To-Do">github</a> profile. </li>
</ul>
<p><strong> Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on  <a target="_blank" href="https://www.twitter.com/JaluiSaurav">Twitter </a> on my coding journey. </strong></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Listing Completed Todos.[11/n]]]></title><description><![CDATA[Welcome back to my series on creating Python APIs using Django REST framework.
Today we will list out the completed Todos in our API view.
Add the below to the urls.py file that you created in the api folder.

The final address would be http://127.0....]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-listing-completed-todos11n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-listing-completed-todos11n</guid><category><![CDATA[Web API]]></category><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[APIs]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 23 Nov 2020 17:57:34 GMT</pubDate><content:encoded><![CDATA[<p>Welcome back to my series on creating Python APIs using Django REST framework.</p>
<p>Today we will list out the completed Todos in our API view.</p>
<p>Add the below to the urls.py file that you created in the <strong>api</strong> folder.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606152532107/n0T21AzAH.png" alt="image.png" /></p>
<p>The final address would be <strong>http://127.0.0.1:8000/api/todos/completed</strong></p>
<p>The view (TodoCompletedList) that you see in the urls.py is what we'll create next in the views.py file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606152633029/TMzgnNaSo.png" alt="image.png" /></p>
<p>We need to create a serializer.py file to map the serializer class to the serializer.py file.</p>
<p>Notice that we have added permission_class in the TodoCompletedList class as well. That is to make sure that only the authenticated users can view the completed todos.</p>
<p>We have defined the get_queryset to make sure we get only the data that we want returned. Make sure you use the exact function <strong>get_queryset</strong> because it is Django REST framework specific.</p>
<p>Also notice that we're returning the same todo objects as we did in out todo.views.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606153433545/jO1ITK8xx.png" alt="image.png" /></p>
<p>Notice in the TodoSerializer class, we have created and datecompleted as read-only field because we don't want users to be able to change those fields.</p>
<p>We have a meta class, where we add the models to retrieve the fields from. We have taken the fields from the todo.models. We do not need to retrieve user field because only authorized users can access the list so no sense displaying that again.</p>
<p>So, now if you go to http://127.0.0.1:8000/api/todos/completed, the following is what you should get. (Make sure the server is running before accessing the API using the command <code>python manage.py runserver</code>)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606410238409/k8rmNrdsl.png" alt="image.png" /></p>
<p>Congratulations! You've successfully listed the completed todos using API. It must feel awesome to have achieved that. In the next article, we will add the basic CRUD (Create, Read, Update, Delete) functionality in the API.</p>
<ul>
<li>You can view the entire code on my <a target="_blank" href="https://github.com/SauravJalui/To-Do">github</a> profile. </li>
</ul>
<p><strong> Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on  <a target="_blank" href="https://www.twitter.com/JaluiSaurav">Twitter </a> on my coding journey. </strong></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Adding the API to an existing app.[10/n]]]></title><description><![CDATA[Now that you have learned how to create a Python API using the Django REST Framework from scratch, let's now use it on an existing project.
We'll use a to-do app that is created using the Django web framework. You can find the link to the code here. ...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-adding-the-api-to-an-existing-app10n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-adding-the-api-to-an-existing-app10n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[Web API]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 19 Nov 2020 18:02:04 GMT</pubDate><content:encoded><![CDATA[<p>Now that you have learned how to create a Python API using the Django REST Framework from scratch, let's now use it on an existing project.</p>
<p>We'll use a to-do app that is created using the Django web framework. You can find the link to the code <a target="_blank" href="https://github.com/SauravJalui/To-Do">here</a>. You can fork the code from there and use it to follow along with me.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605806256241/OHHUQ_r70.png" alt="image.png" /></p>
<p>As you can see the app already had the folders <strong>todo</strong> and <strong>todowoo</strong> folders in it. We add the <strong>api</strong> folder by using the command </p>
<pre><code><span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">startapp</span> <span class="hljs-selector-tag">api</span>
</code></pre><p>also make sure you have the Django REST Framework by using the command </p>
<pre><code><span class="hljs-attribute">pip3</span> install djangorestframework
</code></pre><p>Now that we've added certain new things, let's add it to the <strong>settings.py</strong> of our main project <strong>todowoo</strong></p>
<p>Add <strong>'api', 'restframework', </strong> as shown below.  (<strong>todo</strong> would already be present)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605806620980/gpUXtUXI6.png" alt="image.png" /></p>
<p>After we've done this, let's add the <strong>api</strong> urls in urls.py</p>
<p>We'll have to create new urls.py for that in the <strong>api</strong> folder. </p>
<p>Once we're done creating the file, we can go back to adding the following path to the urls.py of our todowoo folder.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1605807124027/241A8U37U.png" alt="image.png" /></p>
<p>What it basically means is that every url for api is to be fetched will end in "/api" and we will be including in the urls.py for the api folder.</p>
<p>We'll be adding the urls in the next article. Stay tuned for that.</p>
<p>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on  <a target="_blank" href="https://www.twitter.com/JaluiSaurav">Twitter </a> on my coding journey.</p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Deleting Posts.[9/n]]]></title><description><![CDATA[Congratulations! Now you're on the final part of successfully creating your very own basic reddit clone. 
Now for whatever reason, if the user wants to delete his post he should be able to. Let's give him that ability.
We need an url for that, so we ...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-deleting-posts9n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-deleting-posts9n</guid><category><![CDATA[Django]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 16 Nov 2020 18:11:03 GMT</pubDate><content:encoded><![CDATA[<p>Congratulations! Now you're on the final part of successfully creating your very own basic reddit clone. </p>
<p>Now for whatever reason, if the user wants to delete his post he should be able to. Let's give him that ability.</p>
<p>We need an url for that, so we go to the urls.py file and add the url</p>
<pre><code>path(<span class="hljs-string">'api/posts/&lt;int:pk&gt;'</span>, views.PostRetrieveDestroy.as_view()),
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602155958832/ndG4TRyfF.png" alt="image.png" /></p>
<p>Notice the new view, PostRetrieveDestroyView which we have not defined yet.
We will do that in the views.py next.</p>
<p>You can read about PostRetrieveDestroyView <a target="_blank" href="https://www.django-rest-framework.org/api-guide/generic-views/#retrievedestroyapiview">here</a>, and if you go through the documentation you'll also notive there's another view <a target="_blank" href="https://www.django-rest-framework.org/api-guide/generic-views/#retrieveupdatedestroyapiview">RetrieveUpdateDestroyAPIView</a> which might seem more suitable for this. Basically PostRetrieveDestroyView gives you an option to view and delete a post and RetrieveUpdateDestroyAPIView gives you an option to view, update and delete functionality. As you know on Reddit, you cannot edit posts, you have delete your post and create another one. Twitter follows the same, it's because if you create a sensible post that becomes viral, you would have the ability to edit the post to be something unsavory. </p>
<p>Now, we add the PostRetrieveDestroyView, you can use RetrieveUpdateDestroyAPIView as well if you want the users to be able to edit their posts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602156507473/1A7xhCz-I.png" alt="image.png" /></p>
<p>Since it is Post, we can use the same options in <strong>class PostRetrieveDestroy</strong> as we had in <strong>class PostList</strong></p>
<p>Now if you save this and refresh the webpage, this works. But there is a caveat, let me show you:</p>
<p>These are the current posts we have, as you can see we have 3 posts and we are logged in as the user Saurav.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602156822977/SBDxY1Qbx.png" alt="image.png" /></p>
<p>What if I want to delete the 2nd post, let's try deleting it.</p>
<p>We'll use the url <code>http://localhost:8000/api/posts/3</code></p>
<p>Notice the ID for the post is '3', although the post is 2nd. Be careful with the IDs, they should be the one in url and not the post number.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157230583/ARsL25qJo.png" alt="image.png" /></p>
<p>Now click on delete, it will ask if you absolutely want to delete the post.
Click on delete.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157280269/CCkmt_dAD.png" alt="image.png" /></p>
<p>Now if you go to the main page with all the posts, you should see only two posts. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157352827/QgcF4R_Ab.png" alt="image.png" /></p>
<p>Let's login as the other user we created(gaurav) and try to delete a post created by him. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157529204/xmV3YaP0l.png" alt="image.png" /></p>
<p>If you come to the main page now and refresh, you should be able to see all the posts created by Saurav and Gaurav on the same page.</p>
<p>Let's try to delete the post we just created using Gaurav's ID.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157730672/kWaVd2Kr3.png" alt="image.png" /></p>
<p>Notice Gaurav's post ID is 8, make sure you put the correct ID in the url.
The url should be <code>http://localhost:8000/api/posts/8</code></p>
<p>Now, click on delete and voilà!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157828830/GlPsED9DD.png" alt="image.png" /></p>
<p>The post is successfully deleted, you can check on the homepage as well.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602157909583/tvVbSECp5.png" alt="image.png" /></p>
<p>So it is successful, we can delete the post. and it works for all users as well.</p>
<p>Something that is an issue is if you try to delete another user's post. Let's say Gaurav wants to delete a post Saurav created. What would happen?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602158231852/A5Ozz9T_B.png" alt="image.png" /></p>
<p>Gaurav wants to delete the 3rd post by Saurav. Let's see if he can delete.
What do you think should happen?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602158306938/JkEbv8x_J.png" alt="image.png" /></p>
<p>It got deleted!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602158352692/iTxrEyHUW.png" alt="image.png" /></p>
<p>There's only one post that remains now.</p>
<p>Why do you think Gaurav was able to delete Saurav's post?</p>
<p>Think, we've already covered this.</p>
<p>Gaurav is able to delete Saurav's post is because although we've set the permission as "Authenticated or Readonly". Which means to delete the post you need to be authenticated, or you have only read access. We do not check if the user that is making the delete request is the same as the one currently logged in.</p>
<p>Let's fix that!</p>
<p>Add a delete function for the PostRetrieveDestroy class.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602159297561/6_ehzmRu0.png" alt="image.png" /></p>
<p>It is very straightforward, you define a <strong>post</strong> variable where you assign the primary key to that of the post and the poster to be the user making the request. If <strong>post</strong> exists, meaning the user logged in is the user that has created the post with the id, then we invoke the destroy function, else we raise a validation error.</p>
<p>To test this works, I've created a new post logged in as user Gaurav, now let's try to delete it logged in as Saurav.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602159084432/2EWOB5nmZ.png" alt="image.png" /></p>
<p>The id for the post is 9, so the url should be <code>http://localhost:8000/api/posts/9</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602159206830/CTnn80Bh9.png" alt="image.png" /></p>
<p>Let's try to delete that post.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602159386970/yutW4hFqQ.png" alt="image.png" /></p>
<p>Look at that! It is working perfectly now. It crosschecks the user that is logged in with the user that is making the request.</p>
<p>How awesome is that? Congratulations! You have successfully created a basic reddit clone.</p>
<p>Next, we will add an API to an existing project.</p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Deleting Votes.[8/n]]]></title><description><![CDATA[Now that we have enabled the voting functionality, let's say that someone voted for a post they didn't want to vote for. Or for whatever reason they want to take their vote back.
You can create a completely different class based view that uses Destro...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-deleting-votes8n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-deleting-votes8n</guid><category><![CDATA[Django]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 12 Nov 2020 13:00:19 GMT</pubDate><content:encoded><![CDATA[<p>Now that we have enabled the voting functionality, let's say that someone voted for a post they didn't want to vote for. Or for whatever reason they want to take their vote back.</p>
<p>You can create a completely different class based view that uses <strong>DestroyAPIView </strong> But there is a much simpler way to do that.
We can use <a target="_blank" href="https://docs.djangoproject.com/en/3.1/topics/class-based-views/mixins/">Mixin</a> to add a function that will implement the delete functionality for us. </p>
<p>So we start by importing Mixins.</p>
<p><code>from rest_framework import generics,permissions, mixins</code></p>
<p>Add <strong>mixins.DestroyModelMixin</strong> in <code>class VoteCreate(generics.CreateAPIView, mixins.DestroyModelMixin):</code></p>
<p>then create a new delete method, follow the code below with its explanation in inline comments.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602078719855/_PhUypqVw.png" alt="image.png" /></p>
<p>Note we use <strong>Response()</strong> object and <strong>status</strong> so don't forget to import that using the command. You can import status on the same line as mixins as they are both a part of the rest_framework.</p>
<p><code>from rest_framework.response import Response
from rest_framework import generics,permissions, mixins, status</code></p>
<p>So now if you refresh your web page you should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602079070819/8FFiS4XtT.png" alt="image.png" /></p>
<p>You got a nifty button to delete the vote!</p>
<p>When you click on it, it asks if you want to delete the vote.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602079150906/VWwJWeA1G.png" alt="image.png" /></p>
<p>When you click yes, It deletes your vote, and if you try to delete the vote again it says "You did not vote for this post yet". Just as we programmed it to say.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602079265502/veBYqTsiJ.png" alt="image.png" /></p>
<p>Now just because you voted for a post once, and deleted the vote does not mean you would not be able to vote for the same post again.</p>
<p>If you vote on a post again it will give a <strong>HTTP 201 Created</strong> status and also display the vote id.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602079434425/ukqLn7bPo.png" alt="image.png" /></p>
<p>Let's see if the code breaks if you try to vote again for the same post.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602079562699/s2rqlvG2V.png" alt="image.png" /></p>
<p>No! it doesn't break. It's working as expected.</p>
<p>But if you go to the full api list you can't see the total number of votes each post has got. Let's fix that!</p>
<p>Add the following code:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602085779669/afKWiQouk.png" alt="image.png" /></p>
<p>Add <code>votes = serializers.SerializerMethodField()</code> in PostSerializer class.
Make sure you add <code>votes</code> in the fields of Meta class and create function <strong>get_votes</strong></p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_votes</span><span class="hljs-params">(<span class="hljs-keyword">self</span>, post)</span></span>:
    <span class="hljs-keyword">return</span> Vote.objects.filter(post=post).count()
</code></pre><p>After you've done this, if you refresh the page you should see a new field called 'votes' with the total votes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602086061346/Z4EzMxqPJ.png" alt="image.png" /></p>
<p>If you want to make sure it's working you can try to create a new user, logging in as that user and voting on a post.</p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - API auth.[7/n]]]></title><description><![CDATA[In this article, we will be trying to test if our upvote functionality is really working by creating another user and having him upvote the same post.
You can create a new user from the Django admin panel.

But if you see the webpage, we don't have a...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-api-auth7n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-api-auth7n</guid><category><![CDATA[Django]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 09 Nov 2020 14:47:36 GMT</pubDate><content:encoded><![CDATA[<p>In this article, we will be trying to test if our upvote functionality is really working by creating another user and having him upvote the same post.</p>
<p>You can create a new user from the Django admin panel.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601732548517/bIq7_Gdvw.png" alt="image.png" /></p>
<p>But if you see the webpage, we don't have an option to logout and login as another user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601732751784/eKpejg6Bh.png" alt="image.png" /></p>
<p>And if you try to login through the admin panel, it won't let you in as the account we created is not an admin account.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601732841523/cIYuBL4qk.png" alt="image.png" /></p>
<p>So what we can do is we can add a login feature to our API. It's a nifty feature of Django REST framework.</p>
<p>We just need to add the following path in the urls.py file:</p>
<p><code>path('api-auth', include('rest_framework.urls')),</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601733395839/y_yFps307.png" alt="image.png" /></p>
<p>And if you refresh the webpage you would be able to see a login button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601733334289/KCbFKnUac.png" alt="image.png" /></p>
<p>Now, click on login and login as the new user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601734905833/6MZwNCjps.png" alt="image.png" /></p>
<p>And try to upvote the post as gaurav, you shall she the below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601734967777/Y55OP63bo.png" alt="image.png" /></p>
<p>Now if you try to upvote the same post again you would receive the ValidationError that we created, so the code works perfectly.</p>
<p>Now let's go to the admin panel to check if the data is properly added to the database. We can see our new users upvote.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601735417708/VMcEGZKjI.png" alt="image.png" /></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Upvoting Posts.[6/n]]]></title><description><![CDATA[Now that we've added the functionality to create posts via the API, we will now add the ability to upvote the posts. 
So, if we're going to have an API to create a vote, first we need to have a serializer for that vote. Just like we created for the P...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-upvoting-posts6n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-upvoting-posts6n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[Web API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 05 Nov 2020 17:10:36 GMT</pubDate><content:encoded><![CDATA[<p>Now that we've added the functionality to create posts via the API, we will now add the ability to upvote the posts. </p>
<p>So, if we're going to have an API to create a vote, first we need to have a serializer for that vote. Just like we created for the Post.</p>
<p>Go to serializers.py and enter the code as following :</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601727116276/eMgm-9iCK.png" alt="image.png" /></p>
<p>Also remember to import Vote from models using the command <code>from .models import Post, Vote</code></p>
<p>Now, lets move over to our urls.py to see how someone is going to be able to vote for a particular post.</p>
<p>We need the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601727371001/Cfped_DiH.png" alt="image.png" /></p>
<p>The  is what the id of the posts would be. For example: if it is the 1st post then it would be 1, the url would be <code>api/posts/1/vote</code> Since we have multiple posts we can't just define it as 1 in the program.</p>
<p>The view VoteCreate is what we will create next so let's go to the views.py file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601729950006/U0gJnIAho.png" alt="image.png" /></p>
<p>Also don't forget to import Vote from models and VoteSerializer from serializer using the command:</p>
<pre><code><span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> Post, Vote
<span class="hljs-keyword">from</span> .serializers <span class="hljs-keyword">import</span> PostSerializer, VoteSerializer
</code></pre><p>So if you now try to upvote the 1st post using the url <code>http://localhost:8000/api/posts/1/vote</code> You should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601730147941/v7JNw2mct.png" alt="image.png" /></p>
<p>But if you click on post to register the post then we get the following error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601730251850/0LYSQ05Lj.png" alt="image.png" /></p>
<p>We get this error because it has to know what user it has to be able to save this for. So we would need to do the same as we did with Post (the function perform_create)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731170540/R16V6towi.png" alt="image.png" /></p>
<p>After we add that and try to reload the page again and try to vote, this is what we get:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731012279/FchhSaA-M.png" alt="image.png" /></p>
<p>Voilà, we can now vote!</p>
<p>However, there is a catch!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731270004/U2EUj20w0.png" alt="image.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731391804/AIjEvXm2d.png" alt="image.png" /></p>
<p>If you click post multiple times it takes those as valid votes. But we have to restrict that. We can't have multiple votes from a single user. </p>
<p>So we need to check if the user has already voted for a post and we can do that by using the <strong>get_queryset</strong> function that we created.</p>
<p>We just need to add the following condition in the <strong>perform create</strong> function:</p>
<pre><code><span class="hljs-selector-tag">if</span> <span class="hljs-selector-tag">self</span><span class="hljs-selector-class">.get_queryset</span>()<span class="hljs-selector-class">.exists</span>():
    <span class="hljs-selector-tag">raise</span> <span class="hljs-selector-tag">ValidationError</span>(<span class="hljs-string">'You have already upvoted this'</span>)
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731865265/tJWSbwQ70.png" alt="image.png" /></p>
<p>Also don't forget to import the Validation Error using </p>
<p><code>from rest_framework.exceptions import ValidationError</code></p>
<p>If you refresh the webpage and try to vote again, you should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601731925397/qoHzQ8KeQ.png" alt="image.png" /></p>
<p>Congratulations! this was a big step towards creating our API, In the next article we will create a new user and check if he can upvote the post. So far, we've been using the superuser that we created at the beginning to test our API.</p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Creating Posts via API.[5/n]]]></title><description><![CDATA[In the last article, we created the posts using the admin panel. In this article we will add the posts using the API itself. Keep reading to find out more.
All you have to do is change the instance method from ListAPIView to ListCreateAPIView in view...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-creating-posts-via-api5n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-creating-posts-via-api5n</guid><category><![CDATA[Django]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><category><![CDATA[REST API]]></category><category><![CDATA[Web API]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 02 Nov 2020 18:29:01 GMT</pubDate><content:encoded><![CDATA[<p>In the last article, we created the posts using the admin panel. In this article we will add the posts using the API itself. Keep reading to find out more.</p>
<p>All you have to do is change the instance method from ListAPIView to ListCreateAPIView in views.py as we want to not only want to view the posts but also create them.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601647304187/JnNhoR2x6.png" alt="image.png" /></p>
<p>Now if you refresh the browser window, then you should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601647365230/YHP8DDcIH.png" alt="image.png" /></p>
<p>You can now add posts through the form generated on the page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601647481778/ejfeiKPfJ.png" alt="image.png" /></p>
<p>Now if you refresh the page, you would be able to see both the posts that you've added.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601647585816/jv9ArkRWZ.png" alt="image.png" /></p>
<p>Now, you might think that's all we had to do to create posts via the API but that's not true. There's more. </p>
<p>When you try to create a Post using the json data and do not put the poster name, it shows that it cannot be null. Ideally the user should not get an option to select the poster. It should be the logged in user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601647999332/6YuZ_-rAL.png" alt="image.png" /></p>
<p>That's what we're going to change next by making the poster field read-only in the serializer file. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601648291584/eCGXhNtA9.png" alt="image.png" /></p>
<p>Notice that we also added the poster_id to the fields in class Meta.</p>
<p>Now if we refresh our browser window then we'll notice that there is no poster field in both the HTML form and the json field. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601648434115/bHwTxpAeJ.png" alt="image.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601648471604/JBXiqSmCY.png" alt="image.png" /></p>
<p>But when we try to fill the data and try to create the post we get the following error saying someone has to be the poster. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601648574349/w6M3y3DTp.png" alt="image.png" /></p>
<p>So what we can do to solve this error is to override a function just before the API is trying to save the data in the database. </p>
<p>We need to make the following changes in views.py</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601649585219/9UFPlsWj4.png" alt="image.png" /></p>
<p>Now if you refresh and enter the details for the new post, notice it now has a poster and a poster_id field that we just created.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601649501394/AwqldW3Mn.png" alt="image.png" /></p>
<p>We are able to perform these functions because we are logged in as the user. If we copy the url <code>http://localhost:8000/api/posts</code> and post it in another browser and try to create a post it would give the following error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601649902133/hV8LGs2zG.png" alt="image.png" /></p>
<p>Which basically means that we don't have permission to call the API because we are not authenticated. We need to set that in the views.py file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601650155233/7UBAVxCTg.png" alt="image.png" /></p>
<p>Notice that we had to import permissions from rest framework and the instance of the permissions class is 'IsAuthenticatedOrReadonly` which basically means that if you're logged in you can create new post else you can only view the posts, just like reddit.</p>
<p>So, in a browser where you're not logged in you can still view the posts but not create new ones.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601650352614/WOgsanIiA.png" alt="image.png" /></p>
<p>But in a browser where you're logged in you can do both.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601650421191/z-57NeLNY.png" alt="image.png" /></p>
<p>In the next article, we will write code on how to upvote a particular post. Stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Adding Posts to DB.[4/n]]]></title><description><![CDATA[Welcome back to my API series, where I create and integrate an API to our app. This is part 4 of the series, I highly recommend to read the 1st three posts to be able to follow through with this post.
Part 1 : Creating Python APIs - The Django REST f...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-adding-posts-to-db4n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-adding-posts-to-db4n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Web API]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 29 Oct 2020 16:28:35 GMT</pubDate><content:encoded><![CDATA[<p><em> Welcome back to my API series, where I create and integrate an API to our app. This is part 4 of the series, I highly recommend to read the 1st three posts to be able to follow through with this post.</em></p>
<p>Part 1 : <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-basics1n-ckggdzjqt0020sis1dv8s3q3c">Creating Python APIs - The Django REST framework : Basics[1/n]</a> </p>
<p>Part 2 : <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-models2n-ckgl1enby068rows181x6f0nq">Creating Python APIs - The Django REST framework. Building a Reddit clone - Models.[2/n]</a> </p>
<p>Part 3 : <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-serializers3n">Creating Python APIs - The Django REST framework. Building a Reddit clone - Serializers.[3/n]</a> </p>
<p></p>
<p>Now that we've made our 1st ever API call, we need to add some data in the database to display through the API.</p>
<p>The simplest method is creating a superuser and adding posts via the admin panel. </p>
<p>Before creating a superuser make sure we migrate every changes we've made to the model using the command <code>python manage.py migrate</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601640463862/x0Ce08MMP.png" alt="image.png" /></p>
<p>Now we can create a superuser using the command <code>python manage.py createsuperuser</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601640613826/nBhqL2l_U.png" alt="image.png" /></p>
<p>Now that you've created a superuser as well, before accessing the admin panel you need to register our class. We do that in the admin.py file.
If we don't register our classes and start the server to access the admin panel we'd see the below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601640862986/JgB2d-zLl.png" alt="image.png" /></p>
<p>You need to add the following to register the classes we've created:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601642605905/ap6cNGnBe.png" alt="image.png" /></p>
<p>After you've successfully registered the classes run the server using the command <code>python manage.py runserver</code> then type the url <code>http://localhost:8000/admin/</code> as we need to add posts using the admin panel.</p>
<p>You should see the panel as below: </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601642666916/Q59xzGACf.png" alt="image.png" /></p>
<p>Notice you have both the posts and votes in the panel.</p>
<p>Since our API displays the posts, let's create a new post:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601642908012/srfqZnewa.png" alt="image.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601642965484/8D1mbuHyG.png" alt="image.png" /></p>
<p>Now refresh the page with url <code>http://localhost:8000/api/posts</code> and you should see the following: </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601643151033/jOcuNjs-F.png" alt="image.png" /></p>
<p>The first post that you created!</p>
<p>When you display the data on the browser it displays it very neatly in a nice webpage. You can also view the json data on your terminal using the <strong>curl</strong> command.</p>
<p>You can do this by running the server on one terminal window and running the command <code>curl http://localhost:8000/api/posts</code> in another terminal window.</p>
<p>You should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601643468827/7EdxjZqfA.png" alt="image.png" /></p>
<p>This is the same data as we viewed on the webpage when we run the url 
http://localhost:8000/api/posts in the browser, but in json format.</p>
<p><strong> Bonus: </strong></p>
<p>If you want to change the name in the admin panel from "Post Object 1" to displaying the title name, add the following code in the Post class in models.py.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(<span class="hljs-keyword">self</span>)</span></span>:
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">self</span>.title
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601644138490/vyEXjL4ZY.png" alt="image.png" /></p>
<p>Then refresh the page and you should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601644307243/7eABNB3V1.png" alt="image.png" /></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Serializers.[3/n]]]></title><description><![CDATA[Welcome back to my API series, where I create and integrate an API to our app. This is part 3 of the series, I highly recommend to read the 1st two posts to be able to follow through with this post.
Part 1 : Creating Python APIs - The Django REST fra...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-serializers3n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-serializers3n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Web API]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 26 Oct 2020 17:19:22 GMT</pubDate><content:encoded><![CDATA[<p><em> Welcome back to my API series, where I create and integrate an API to our app. This is part 3 of the series, I highly recommend to read the 1st two posts to be able to follow through with this post.</em></p>
<p>Part 1 : <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-basics1n-ckggdzjqt0020sis1dv8s3q3c">Creating Python APIs - The Django REST framework : Basics[1/n]</a> </p>
<p>Part 2 : <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-models2n-ckgl1enby068rows181x6f0nq">Creating Python APIs - The Django REST framework. Building a Reddit clone - Models.[2/n]</a> </p>
<p></p>
<p>So in the last part, we created a model. Now it's time to start building the API. There are two ways of going about that:</p>
<p>A) You can create the API from scratch.</p>
<p>OR </p>
<p>B) You can use the Django REST framework which does all the heavy lifting for us.</p>
<p>You could not go wrong with either of the two but using the first option, although as enticing as it sounds can get very complicated very fast.</p>
<p>I want to make understanding APIs easier so I'll be using the second method and I promise it'll leave you hooked. Once you get an idea how API works and what you can do with it you can get your hands dirty with the 1st option.</p>
<p>You can read about the Django REST framework  <a target="_blank" href="https://www.django-rest-framework.org/">here</a>: It is very well documented and very beginner friendly. </p>
<p>There are wonderful tutorials to get you acquainted with the framework. Do give it a read.</p>
<p>So now we'll install the framework using the pip command in our terminal/command prompt:</p>
<p><code>pip install djangorestframework</code></p>
<p><em> Remember the word <strong>djangorestframework</strong> is all one word with no spaces </em></p>
<p>After we've successfully installed Django REST framework, now it's time to add it into our project.</p>
<p>We need to add <code>rest_framework</code> under the Installed apps in settings.py as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601554390113/vS0NmUlrY.png" alt="image.png" /></p>
<p>Now you might be curious about why is it called Django <strong>REST</strong> framework.</p>
<p>So REST API is an API that follows a certain standard. It has it's own architectural style which you can read about  <a target="_blank" href="https://restfulapi.net/">here</a>.</p>
<p>Now that we're done with this, lets talk about serializers.</p>
<h3 id="what-are-serializers">What are serializers?</h3>
<p>Serializers are a way to be the middleman between the models and the APIs. So it basically converts the Django models into json objects and vice versa.</p>
<p>We'll create a new file in our posts app called the serializers.py (You can name this anything you want but this name is what the REST framework suggests)</p>
<p>The explanation of what each line does is inline in the comments:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601637680444/aI-3mrCXl.png" alt="image.png" /></p>
<p>After this is done, save this and now we will create API urls. So we will begin by adding new path in the urls.py file as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601638184715/-bdZ1DAee.png" alt="image.png" /></p>
<p>Now, you might be confused as to what the <code>views.PostList.as_view()</code> mean as we don't have that view yet. Don't worry, we will create that view next.</p>
<p>You can read more about Generic views that we imported in views <a target="_blank" href="https://www.django-rest-framework.org/api-guide/generic-views/">here</a> </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601639429135/bncokrZbj.png" alt="image.png" /></p>
<p>This is all we need for our very first API call.</p>
<p>Now run the server and if you go to <code>http://127.0.0.1:8000/</code> you'd see the following screen. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601639683468/ID6ckmKyM.png" alt="image.png" /></p>
<p>But don't worry that's completely normal, since we created a url for api/posts, so if you edit the url to display <code>http://127.0.0.1:8000/api/posts</code>
You should see the following screen.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601639903051/z-isqXp-T.png" alt="image.png" /></p>
<p>Congratulations! You just made your first API call, although this might not look like much but this is a massive step. The reason it doesn't show any data because we don't have anything saved in the database yet.</p>
<p>In the next posts we'll diver deeper into adding and displaying more information.</p>
<p><b><em>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on Twitter on my <a target="_blank" href="https://twitter.com/JaluiSaurav">coding </a> journey.</em></b></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework. Building a Reddit clone - Models.[2/n]]]></title><description><![CDATA[This is the 2nd part of the Creating Python API series, If you haven't read the 1st article go read about it here. 
 Let's begin!

I believe the best way to learn is by doing so we're going to be making our own reddit clone in this article.
We'll not...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-models2n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-building-a-reddit-clone-models2n</guid><category><![CDATA[Django]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Web API]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 22 Oct 2020 16:25:51 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1603382464601/21o8gExQ8.jpeg" alt="Rest-API-introduction.jpg" /></p>
<p><em>This is the 2nd part of the Creating Python API series, If you haven't read the 1st article go read about it <a target="_blank" href="https://sauravjalui.hashnode.dev/creating-python-apis-the-django-rest-framework-basics1n">here</a>. </em></p>
<h3> Let's begin!</h3>

<p>I believe the best way to learn is by doing so we're going to be making our own reddit clone in this article.</p>
<p>We'll not be making a full fledged Reddit clone with all its features, rather we will be making a simpler version of it. We will create a service where people post links and upvote them using Django and making an API for it.</p>
<h3 id="creating-the-django-app">Creating the Django app</h3>
<p>A) Open your terminal and go to your desktop (or any preferred location where you want to save the project).</p>
<p>Use the command: <code>cd Desktop</code></p>
<p>B) Create the project using the command: <code>django-admin startproject reddit</code></p>
<p>I used reddit, you can name the app anything you like.</p>
<p>I later change the project name manually from reddit to reddit-project because it makes it easier to distinguish the top level folder.</p>
<p>C) You can check if it has all been created properly by using the command: <code>python manage.py runserver</code> (It can be Python/Python3 depending on the version of Python you have installed on your computer. I have only Python3 installed so even if I use Python it knows I mean Python3. If you have both the versions installed you would need to explicitly specify the python version).</p>
<p>You should see the following in your terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601303296121/9fVWHBjWJ.jpeg" alt="runserver.jpg" /></p>
<p>And the following in your browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601303411505/qxE9Am9eu.jpeg" alt="installedsuccess.jpg" /></p>
<p>This means we've followed the steps correctly, now we can move on to create the Posts app.</p>
<p>D) Since we will be having posts in our service we need to create a Posts app by running the command: <code>python manage.py startapp posts</code></p>
<p>Open the folder using your favorite code editor - I use vscode. You'd see the following folder structure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601303665712/JQYKeEAWM.jpeg" alt="posts.jpg" /></p>
<p>E) After creating the posts app, add it in the settings.py under installed apps as below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601304921734/sgkNuzPyZ.png" alt="image.png" /></p>
<p>F) Then go to the models.py and type the following code:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601304758331/omjD4ff1B.png" alt="image.png" /></p>
<p>Explanation of each line is under the line in the comments.</p>
<p>G) After creating the model we need to migrate the model by using the command <strong>
<em> (Remember to always migrate the model after you make any changes to it </em>) </strong></p>
<p><code>python manage.py makemigrations</code></p>
<p>You should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601305141463/xl7JBphKB.png" alt="image.png" /></p>
<p>which means there was no error in making migrations. We can successfully migrate now using the command <code>python manage.py migrate</code></p>
<p>You should see the following: </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601305284937/msP4oZ4un.png" alt="image.png" /></p>
<p>This updates the database for us. This was a very big first step to get the project started but we have a strong foundation now and we can start building this thing.</p>
<p><b><em>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on Twitter on my <a target="_blank" href="https://twitter.com/JaluiSaurav">coding </a> journey.</em></b></p>
]]></content:encoded></item><item><title><![CDATA[Creating Python APIs - The Django REST framework : Basics[1/n]]]></title><description><![CDATA[Photo from  Dreamstime.com 
What is an API?
I'm not going to be talking about the technical definition here, you can find that on Wikipedia.
What I'm going to talk about however is what APIs are in real life, where they are used and why they are impo...]]></description><link>https://sauravjalui.com/creating-python-apis-the-django-rest-framework-basics1n</link><guid isPermaLink="true">https://sauravjalui.com/creating-python-apis-the-django-rest-framework-basics1n</guid><category><![CDATA[Python 3]]></category><category><![CDATA[REST API]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Django]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 19 Oct 2020 10:19:11 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601295483914/4Cbavv5aM.jpeg" alt="Rest-API-introduction.jpg" />
Photo from  <a target="_blank" href="https://thumbs.dreamstime.com/z/api-interface-vector-icon-style-illustration-data-custom-user-experience-ui-ux-79867156.jpg">Dreamstime.com</a> </p>
<h3 id="what-is-an-api">What is an API?</h3>
<p></p><p>I'm not going to be talking about the technical definition here, you can find that on <a target="_blank" href="https://en.wikipedia.org/wiki/API">Wikipedia</a>.</p>
<p>What I'm going to talk about however is what APIs are in real life, where they are used and why they are important?
For example, when you're developing MAC or iOS apps, there is an API that connects with the OS, we're not discussing that. </p>
<p>We are going to talk about Web APIs.</p>
<h3 id="so-why-are-apis-important">So why are APIs important?</h3>
<p>Let's say you want to scrape Twitter and display the trending topics on your website. This will work but will be inefficient because it depends on the website and its items not changing. So if twitter decides to move the trending tab's position then your scraper will break.</p>
<p>The correct way to deal with this is to use the Twitter API.
For example, if you're trying to get tweet timelines then the request would be something like -</p>
<p><code>GET https://api.twitter.com/1.1/statuses/home_timeline.json</code></p>
<p>and the response would be something like this -</p>
<pre><code class="lang-{">  "created_at": "Wed Oct 10 20:19:24 +0000 2018",  "id": 1050118621198921728,`
  "id_str": "1050118621198921728",
  "text": "To make room for more expression, we will now count all emojis as equal—including those with gender‍‍‍ and skin t… https://t.co/MkGjXf9aXm",
  "truncated": true,
  "entities": {
    "hashtags": [],
    "symbols": [],
    "user_mentions": [], ...
</code></pre>
<p>The response will be in .json(JavaScript object notation) format and will be much bigger than this but you get the gist.</p>
<p>There are other ways to display the data as well, like CSVs and XML format files but Json is so widely used it is the standard now.</p>
<p>The Json file basically says that this is how the data will be received. The 'h' in <em>'hashtags'</em> won't change from 'h' to 'H'. It would remain constant. The Json file is the machine code and will be in the background. You will see the Twitter timeline and not the code behind it.</p>
<h3 id="where-are-apis-used">Where are APIs used?</h3>
<ol>
<li>Lets say you have a website and you want to make an app, API is the way to do it. </li>
<li>If you want to display the weather data on your website then you can use the API of a broadcasting site and use it in your website to display the weather. So that adds additional functionality to your website.</li>
<li>You can use the Google Maps API to embed a map in your website.</li>
</ol>
<p>and many more.</p>
<p><em>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on Twitter on my  <a target="_blank" href="https://twitter.com/JaluiSaurav">coding </a> journey.</em></p>
<p><strong> <em>This is the 1st article of creating Python APIs series, stay tuned for the remaining blog posts. We will at make an API and implement it in one of the apps we made using Django! </em></strong> </p>
]]></content:encoded></item><item><title><![CDATA[Hide your secret API keys!]]></title><description><![CDATA[Photo from Medium 
Why should you hide your API keys?
If you are working on a project and want to make the code public (on GitHub) then it's very important that you hide the secret API key before pushing it to GitHub.
Your API keys are like your pass...]]></description><link>https://sauravjalui.com/hide-your-secret-api-keys</link><guid isPermaLink="true">https://sauravjalui.com/hide-your-secret-api-keys</guid><category><![CDATA[Web API]]></category><category><![CDATA[REST API]]></category><category><![CDATA[Django]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Thu, 15 Oct 2020 14:52:42 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://miro.medium.com/max/2400/1*4AulM5jaalYHhEukt7KJnw.png" /> 
Photo from <a target="_blank" href="https://miro.medium.com/max/2400/1*4AulM5jaalYHhEukt7KJnw.png">Medium</a> </p>
<h3 id="why-should-you-hide-your-api-keys">Why should you hide your API keys?</h3>
<p>If you are working on a project and want to make the code public (on GitHub) then it's very important that you hide the secret API key before pushing it to GitHub.</p>
<p>Your API keys are like your passwords that you shouldn't tell anyone because using your API keys they would be able to control your website and make changes to it or worse, delete it.</p>
<p>I'll show you a simple way of hiding it using Django.</p>
<h4 id="you-need-the-following-3-files">You need the following 3 files:</h4>
<p>A) config.py - This is where we will store our Key.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601358537802/WqFhwsgIj.png" alt="image.png" /></p>
<p>B) settings.py - Where the key originally is. (it might differ for you based on the stack you're using) </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601357568304/eJYbKzANi.png" alt="image.png" /></p>
<p>We need to import the config from the folder which is reddit using the command <code>from reddit import config</code> and then for the secret we can access it using the command <code>config.SECRET_KEY</code></p>
<p><em> Remember, this is case sensitive and will not work if the cases don't match exactly. And remember to import from the correct folder. </em></p>
<p>C) .gitignore - This is a very crucial file, this is where we add the files, folders that we want to exclude from being uploaded to GitHub.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601358574361/x9vxekgWJ.png" alt="image.png" /></p>
<p>There are a lot of other files, folders that you can include depending on the language you're using as the editor and stack you use may create residual files. Check out  <a target="_blank" href="https://www.toptal.com/developers/gitignore">gitignore.io</a> where you can specify the language you're using and it generates the .gitignore file for you which you can paste in your project files. How awesome is that? </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601358273464/PKok-kSa9.png" alt="image.png" /></p>
<p>This is a raw file so you can easily copy paste the details in your own .gitignore file.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601358350598/b-XevdRWj.png" alt="image.png" /></p>
<p>Did I mention it is opensource? So you can tinker with the website and make it your own. You can also add/edit the templates. Go try it out!</p>
<p>After you're done with the above steps, now it's time to add all the modifications using <code>git add -A</code></p>
<p>You'll notice the files, folders that you added in <em>.gitignore</em> file is not in the list of files that is added. <em>.gitignore</em> file however will be added and that's completely safe.</p>
<p>Commit the changes and push the code on GitHub!</p>
<p><em> <strong> Give yourself a pat on the back because you just secured your project. Great job! </strong></em></p>
<p>p.s. I am aware of the another method of environment variables but I believe the above method is the most efficient, so I explained only about this one. Let me know if you're interested in learning more about using the environment variables to hide your API keys and I shall deliver.</p>
<p><em><strong> Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on Twitter on my  <a target="_blank" href="https://twitter.com/JaluiSaurav">coding </a> journey. </strong></em></p>
]]></content:encoded></item><item><title><![CDATA[How to set up an isolated Python environment?]]></title><description><![CDATA[Image from CultureGeek 
Why create a Python Virtual Environment (venv) ?
Using the Python venv module, you can create an isolated environment to test different combination of packages without it affecting the main installation.
You can have different...]]></description><link>https://sauravjalui.com/how-to-set-up-an-isolated-python-environment</link><guid isPermaLink="true">https://sauravjalui.com/how-to-set-up-an-isolated-python-environment</guid><category><![CDATA[Python]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 12 Oct 2020 11:58:38 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602504049301/xr9UvMcPg.jpeg" alt="venv.jpg" /></p>
<p> <a target="_blank" href="https://culturegeek.ninja/wp-content/uploads/2019/10/virtual_env.png">Image from CultureGeek</a> </p>
<h3 id="why-create-a-python-virtual-environment-venv">Why create a Python Virtual Environment (venv) ?</h3>
<p>Using the Python <code>venv</code> module, you can create an isolated environment to test different combination of packages without it affecting the main installation.</p>
<p>You can have different combinations of packages for different projects in your virtual environment without having to install it on the main system</p>
<p>Additionally, you won't need administrator permissions to install those packages.</p>
<p>Since version 3.3, Python comes with <code>venv</code> installed. So you won't need to install it manually. If however for some reason you do not have <code>venv</code> installed, you can install it using the following command :</p>
<pre><code><span class="hljs-attribute">pip</span> install virtualenv
</code></pre><h3 id="creating-the-virtual-environment">Creating the virtual environment.</h3>
<p>You must specify a path where you want to create a virtual environment.
For example, you can create one in your local directory using the command:</p>
<p><code>virtualenv my_env</code></p>
<p>You can use any name you want for your virtual environment instead of the name 'my_env'</p>
<h3 id="activating-the-virtual-environment">Activating the virtual environment.</h3>
<p>Just creating the environment is not enough, you need to activate it to use it. You can activate it by running the command:</p>
<p><strong>For Windows</strong></p>
<pre><code>my_env\Scripts\activate
</code></pre><p><strong>For MacOS/Linux</strong></p>
<pre><code><span class="hljs-keyword">source</span> my_env/bin/activate
</code></pre><p>Upon successful activation you would see the name of your environment in brackets before the path in terminal like this:</p>
<pre><code>(my_env) C:\Users\Saurav\projects\blog&gt;
</code></pre><h3 id="deactivating-the-virtual-environment">Deactivating the virtual environment.</h3>
<p>It is recommended to always deactivate the virtual environment when you done. You can do that using the command:</p>
<pre><code>deactivate
</code></pre><p>Provided you are in the activated virtual environment, the above command will deactivate it.</p>
<p><strong>Congratulations! You just created a Virtual Environment for your python packages. Explore and experiment away! </strong></p>
<p><em>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on Twitter on my <a target="_blank" href="https://twitter.com/JaluiSaurav">coding</a> journey.</em></p>
]]></content:encoded></item><item><title><![CDATA[How to solve error : command 'x86_64-linux-gnu-gcc' failed with exit status 1]]></title><description><![CDATA[(Photo from Kali)
I'm learning ethical hacking and practicing in Kali, Maybe you're doing the same or maybe you're just trying Linux. While installing a package (netfilterqueue in my case) you encountered this error, How do you go around solving it? ...]]></description><link>https://sauravjalui.com/how-to-solve-error-command-x8664-linux-gnu-gcc-failed-with-exit-status-1</link><guid isPermaLink="true">https://sauravjalui.com/how-to-solve-error-command-x8664-linux-gnu-gcc-failed-with-exit-status-1</guid><category><![CDATA[Linux]]></category><category><![CDATA[hacking]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Wed, 26 Aug 2020 17:02:41 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598457699056/SOjtJoHKD.png" alt="kalihelloitsliam.png" />
(Photo from <a target="_blank" href="https://www.helloitsliam.com/wp-content/uploads/2014/12/kali.png">Kali</a>)</p>
<p>I'm learning ethical hacking and practicing in Kali, Maybe you're doing the same or maybe you're just trying Linux. While installing a package (netfilterqueue in my case) you encountered this error, How do you go around solving it? </p>
<p><strong>Let me tell you how I solved it.</strong></p>
<p>You followed the steps you use when installing a package:</p>
<ul>
<li>Open Terminal and type <br />
<code>pip install netfilterqueue</code> for Python 2 <br />
<code>pip3 install netfilterqueue</code> for Python 3 <br />
and you receive the following error:</li>
</ul>
<pre><code>Collecting netfilterqueue
  Using cached NetfilterQueue<span class="hljs-number">-0.8</span><span class="hljs-number">.1</span>.tar.gz (<span class="hljs-number">58</span> kB)
Using legacy <span class="hljs-string">'setup.py install'</span> <span class="hljs-keyword">for</span> netfilterqueue, since package <span class="hljs-string">'wheel'</span> <span class="hljs-keyword">is</span> not installed.
Installing collected packages: netfilterqueue
    Running setup.py install <span class="hljs-keyword">for</span> netfilterqueue: started
    Running setup.py install <span class="hljs-keyword">for</span> netfilterqueue: finished with status <span class="hljs-string">'error'</span>

DEPRECATION: The -b/--build/--build-dir/--build-directory option <span class="hljs-keyword">is</span> deprecated. pip <span class="hljs-number">20.3</span> will remove support <span class="hljs-keyword">for</span> <span class="hljs-keyword">this</span> functionality. A possible replacement <span class="hljs-keyword">is</span> use the TMPDIR/TEMP/TMP environment variable, possibly combined with --no-clean. You can find discussion regarding <span class="hljs-keyword">this</span> at https:<span class="hljs-comment">//github.com/pypa/pip/issues/8333.</span>
    ERROR: Command errored <span class="hljs-keyword">out</span> with exit status <span class="hljs-number">1</span>:
     command: /root/PycharmProjects/net_cut/venv/bin/python -u -c <span class="hljs-string">'import sys, setuptools, tokenize; sys.argv[0] = '</span><span class="hljs-string">"'"</span><span class="hljs-string">'/tmp/pycharm-packaging/netfilterqueue/setup.py'</span><span class="hljs-string">"'"</span><span class="hljs-string">'; __file__='</span><span class="hljs-string">"'"</span><span class="hljs-string">'/tmp/pycharm-packaging/netfilterqueue/setup.py'</span><span class="hljs-string">"'"</span><span class="hljs-string">';f=getattr(tokenize, '</span><span class="hljs-string">"'"</span><span class="hljs-string">'open'</span><span class="hljs-string">"'"</span><span class="hljs-string">', open)(__file__);code=f.read().replace('</span><span class="hljs-string">"'"</span><span class="hljs-string">'\r\n'</span><span class="hljs-string">"'"</span><span class="hljs-string">', '</span><span class="hljs-string">"'"</span><span class="hljs-string">'\n'</span><span class="hljs-string">"'"</span><span class="hljs-string">');f.close();exec(compile(code, __file__, '</span><span class="hljs-string">"'"</span><span class="hljs-string">'exec'</span><span class="hljs-string">"'"</span><span class="hljs-string">'))'</span> install --record /tmp/pip-record-nzfnyzkz/install-record.txt --single-version-externally-managed --compile --install-headers /root/PycharmProjects/net_cut/venv/include/site/python3<span class="hljs-number">.8</span>/netfilterqueue
         cwd: /tmp/pycharm-packaging/netfilterqueue/
    <span class="hljs-function">Complete <span class="hljs-title">output</span> (<span class="hljs-params"><span class="hljs-number">114</span> lines</span>):
    running install
    running build
    running build_ext
    building 'netfilterqueue' extension
    creating build
    creating build/temp.linux-x86_64-3.8
    x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror</span>=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=<span class="hljs-number">2</span> -fPIC -I/root/PycharmProjects/net_cut/venv/include -I/usr/include/python3<span class="hljs-number">.8</span> -c netfilterqueue.c -o build/temp.linux-x86_64<span class="hljs-number">-3.8</span>/netfilterqueue.o
    netfilterqueue.c: In function ‘__pyx_f_14netfilterqueue_6Packet_set_nfq_data’:
    netfilterqueue.c:<span class="hljs-number">2150</span>:<span class="hljs-number">68</span>: warning: passing argument <span class="hljs-number">2</span> of ‘nfq_get_payload’ <span class="hljs-keyword">from</span> incompatible pointer type [-Wincompatible-pointer-types]
     <span class="hljs-number">2150</span> |   __pyx_v_self-&gt;payload_len = nfq_get_payload(__pyx_v_self-&gt;_nfa, (&amp;__pyx_v_self-&gt;payload));
          |                                                                   ~^~~~~~~~~~~~~~~~~~~~~~~
          |                                                                    |
          |                                                                    <span class="hljs-keyword">char</span> **
    In file included <span class="hljs-keyword">from</span> netfilterqueue.c:<span class="hljs-number">440</span>:
    /usr/include/libnetfilter_queue/libnetfilter_queue.h:<span class="hljs-number">122</span>:<span class="hljs-number">67</span>: note: expected ‘unsigned <span class="hljs-keyword">char</span> **’ but argument <span class="hljs-keyword">is</span> of type ‘<span class="hljs-keyword">char</span> **’
      <span class="hljs-number">122</span> | <span class="hljs-function"><span class="hljs-keyword">extern</span> <span class="hljs-keyword">int</span> <span class="hljs-title">nfq_get_payload</span>(<span class="hljs-params"><span class="hljs-keyword">struct</span> nfq_data *nfad, unsigned <span class="hljs-keyword">char</span> **data</span>)</span>;
          |                                                   ~~~~~~~~~~~~~~~~^~~~
    netfilterqueue.c: In function ‘__pyx_pf_14netfilterqueue_6Packet_4get_hw’:
    netfilterqueue.c:<span class="hljs-number">2533</span>:<span class="hljs-number">17</span>: warning: <span class="hljs-keyword">implicit</span> declaration of function ‘PyString_FromStringAndSize’; did you mean ‘PyBytes_FromStringAndSize’? [-Wimplicit-function-declaration]
     <span class="hljs-number">2533</span> |     __pyx_t_3 = PyString_FromStringAndSize(((<span class="hljs-keyword">char</span> *)__pyx_v_self-&gt;hw_addr), <span class="hljs-number">8</span>); <span class="hljs-keyword">if</span> (unlikely(!__pyx_t_3)) __PYX_ERR(<span class="hljs-number">0</span>, <span class="hljs-number">111</span>, __pyx_L1_error)
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~
          |                 PyBytes_FromStringAndSize
    netfilterqueue.c:<span class="hljs-number">2533</span>:<span class="hljs-number">15</span>: warning: assignment to ‘PyObject *’ {aka ‘<span class="hljs-keyword">struct</span> _object *’} <span class="hljs-keyword">from</span> ‘<span class="hljs-keyword">int</span>’ makes pointer <span class="hljs-keyword">from</span> integer without a cast [-Wint-conversion]
     <span class="hljs-number">2533</span> |     __pyx_t_3 = PyString_FromStringAndSize(((<span class="hljs-keyword">char</span> *)__pyx_v_self-&gt;hw_addr), <span class="hljs-number">8</span>); <span class="hljs-keyword">if</span> (unlikely(!__pyx_t_3)) __PYX_ERR(<span class="hljs-number">0</span>, <span class="hljs-number">111</span>, __pyx_L1_error)
          |               ^
    netfilterqueue.c: In function ‘PyInit_netfilterqueue’:
    netfilterqueue.c:<span class="hljs-number">6111</span>:<span class="hljs-number">3</span>: warning: ‘tp_print’ <span class="hljs-keyword">is</span> deprecated [-Wdeprecated-declarations]
     <span class="hljs-number">6111</span> |   __pyx_type_14netfilterqueue_Packet.tp_print = <span class="hljs-number">0</span>;
          |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/<span class="hljs-keyword">object</span>.h:<span class="hljs-number">746</span>,
                     <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/pytime.h:<span class="hljs-number">6</span>,
                     <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/Python.h:<span class="hljs-number">85</span>,
                     <span class="hljs-keyword">from</span> netfilterqueue.c:<span class="hljs-number">4</span>:
    /usr/include/python3<span class="hljs-number">.8</span>/cpython/<span class="hljs-keyword">object</span>.h:<span class="hljs-number">260</span>:<span class="hljs-number">30</span>: note: declared here
      <span class="hljs-number">260</span> |     Py_DEPRECATED(<span class="hljs-number">3.8</span>) <span class="hljs-keyword">int</span> (*tp_print)(PyObject *, FILE *, <span class="hljs-keyword">int</span>);
          |                              ^~~~~~~~
    netfilterqueue.c:<span class="hljs-number">6116</span>:<span class="hljs-number">3</span>: warning: ‘tp_print’ <span class="hljs-keyword">is</span> deprecated [-Wdeprecated-declarations]
     <span class="hljs-number">6116</span> |   __pyx_type_14netfilterqueue_NetfilterQueue.tp_print = <span class="hljs-number">0</span>;
          |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/<span class="hljs-keyword">object</span>.h:<span class="hljs-number">746</span>,
                     <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/pytime.h:<span class="hljs-number">6</span>,
                     <span class="hljs-keyword">from</span> /usr/include/python3<span class="hljs-number">.8</span>/Python.h:<span class="hljs-number">85</span>,
                     <span class="hljs-keyword">from</span> netfilterqueue.c:<span class="hljs-number">4</span>:
    /usr/include/python3<span class="hljs-number">.8</span>/cpython/<span class="hljs-keyword">object</span>.h:<span class="hljs-number">260</span>:<span class="hljs-number">30</span>: note: declared here
      <span class="hljs-number">260</span> |     Py_DEPRECATED(<span class="hljs-number">3.8</span>) <span class="hljs-keyword">int</span> (*tp_print)(PyObject *, FILE *, <span class="hljs-keyword">int</span>);
          |                              ^~~~~~~~
    netfilterqueue.c: In function ‘__Pyx_PyCFunction_FastCall’:
    netfilterqueue.c:<span class="hljs-number">6436</span>:<span class="hljs-number">13</span>: error: too many arguments to function ‘(PyObject * (*)(PyObject *, PyObject * <span class="hljs-keyword">const</span>*, Py_ssize_t))meth’
     <span class="hljs-number">6436</span> |     <span class="hljs-keyword">return</span> (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs, NULL);
          |            ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    netfilterqueue.c: In function ‘__Pyx__ExceptionSave’:
    netfilterqueue.c:<span class="hljs-number">7132</span>:<span class="hljs-number">21</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_type’; did you mean ‘curexc_type’?
     <span class="hljs-number">7132</span> |     *type = tstate-&gt;exc_type;
          |                     ^~~~~~~~
          |                     curexc_type
    netfilterqueue.c:<span class="hljs-number">7133</span>:<span class="hljs-number">22</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_value’; did you mean ‘curexc_value’?
     <span class="hljs-number">7133</span> |     *<span class="hljs-keyword">value</span> = tstate-&gt;exc_value;
          |                      ^~~~~~~~~
          |                      curexc_value
    netfilterqueue.c:<span class="hljs-number">7134</span>:<span class="hljs-number">19</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_traceback’; did you mean ‘curexc_traceback’?
     <span class="hljs-number">7134</span> |     *tb = tstate-&gt;exc_traceback;
          |                   ^~~~~~~~~~~~~
          |                   curexc_traceback
    netfilterqueue.c: In function ‘__Pyx__ExceptionReset’:
    netfilterqueue.c:<span class="hljs-number">7141</span>:<span class="hljs-number">24</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_type’; did you mean ‘curexc_type’?
     <span class="hljs-number">7141</span> |     tmp_type = tstate-&gt;exc_type;
          |                        ^~~~~~~~
          |                        curexc_type
    netfilterqueue.c:<span class="hljs-number">7142</span>:<span class="hljs-number">25</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_value’; did you mean ‘curexc_value’?
     <span class="hljs-number">7142</span> |     tmp_value = tstate-&gt;exc_value;
          |                         ^~~~~~~~~
          |                         curexc_value
    netfilterqueue.c:<span class="hljs-number">7143</span>:<span class="hljs-number">22</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_traceback’; did you mean ‘curexc_traceback’?
     <span class="hljs-number">7143</span> |     tmp_tb = tstate-&gt;exc_traceback;
          |                      ^~~~~~~~~~~~~
          |                      curexc_traceback
    netfilterqueue.c:<span class="hljs-number">7144</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_type’; did you mean ‘curexc_type’?
     <span class="hljs-number">7144</span> |     tstate-&gt;exc_type = type;
          |             ^~~~~~~~
          |             curexc_type
    netfilterqueue.c:<span class="hljs-number">7145</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_value’; did you mean ‘curexc_value’?
     <span class="hljs-number">7145</span> |     tstate-&gt;exc_value = <span class="hljs-keyword">value</span>;
          |             ^~~~~~~~~
          |             curexc_value
    netfilterqueue.c:<span class="hljs-number">7146</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_traceback’; did you mean ‘curexc_traceback’?
     <span class="hljs-number">7146</span> |     tstate-&gt;exc_traceback = tb;
          |             ^~~~~~~~~~~~~
          |             curexc_traceback
    netfilterqueue.c: In function ‘__Pyx__GetException’:
    netfilterqueue.c:<span class="hljs-number">7201</span>:<span class="hljs-number">24</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_type’; did you mean ‘curexc_type’?
     <span class="hljs-number">7201</span> |     tmp_type = tstate-&gt;exc_type;
          |                        ^~~~~~~~
          |                        curexc_type
    netfilterqueue.c:<span class="hljs-number">7202</span>:<span class="hljs-number">25</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_value’; did you mean ‘curexc_value’?
     <span class="hljs-number">7202</span> |     tmp_value = tstate-&gt;exc_value;
          |                         ^~~~~~~~~
          |                         curexc_value
    netfilterqueue.c:<span class="hljs-number">7203</span>:<span class="hljs-number">22</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_traceback’; did you mean ‘curexc_traceback’?
     <span class="hljs-number">7203</span> |     tmp_tb = tstate-&gt;exc_traceback;
          |                      ^~~~~~~~~~~~~
          |                      curexc_traceback
    netfilterqueue.c:<span class="hljs-number">7204</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_type’; did you mean ‘curexc_type’?
     <span class="hljs-number">7204</span> |     tstate-&gt;exc_type = local_type;
          |             ^~~~~~~~
          |             curexc_type
    netfilterqueue.c:<span class="hljs-number">7205</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_value’; did you mean ‘curexc_value’?
     <span class="hljs-number">7205</span> |     tstate-&gt;exc_value = local_value;
          |             ^~~~~~~~~
          |             curexc_value
    netfilterqueue.c:<span class="hljs-number">7206</span>:<span class="hljs-number">13</span>: error: ‘PyThreadState’ {aka ‘<span class="hljs-keyword">struct</span> _ts’} has no member named ‘exc_traceback’; did you mean ‘curexc_traceback’?
     <span class="hljs-number">7206</span> |     tstate-&gt;exc_traceback = local_tb;
          |             ^~~~~~~~~~~~~
          |             curexc_traceback
    error: command <span class="hljs-string">'x86_64-linux-gnu-gcc'</span> failed with exit status <span class="hljs-number">1</span>
    ----------------------------------------
ERROR: Command errored <span class="hljs-keyword">out</span> with exit status <span class="hljs-number">1</span>: /root/PycharmProjects/net_cut/venv/bin/python -u -c <span class="hljs-string">'import sys, setuptools, tokenize; sys.argv[0] = '</span><span class="hljs-string">"'"</span><span class="hljs-string">'/tmp/pycharm-packaging/netfilterqueue/setup.py'</span><span class="hljs-string">"'"</span><span class="hljs-string">'; __file__='</span><span class="hljs-string">"'"</span><span class="hljs-string">'/tmp/pycharm-packaging/netfilterqueue/setup.py'</span><span class="hljs-string">"'"</span><span class="hljs-string">';f=getattr(tokenize, '</span><span class="hljs-string">"'"</span><span class="hljs-string">'open'</span><span class="hljs-string">"'"</span><span class="hljs-string">', open)(__file__);code=f.read().replace('</span><span class="hljs-string">"'"</span><span class="hljs-string">'\r\n'</span><span class="hljs-string">"'"</span><span class="hljs-string">', '</span><span class="hljs-string">"'"</span><span class="hljs-string">'\n'</span><span class="hljs-string">"'"</span><span class="hljs-string">');f.close();exec(compile(code, __file__, '</span><span class="hljs-string">"'"</span><span class="hljs-string">'exec'</span><span class="hljs-string">"'"</span><span class="hljs-string">'))'</span> install --record /tmp/pip-record-nzfnyzkz/install-record.txt --single-version-externally-managed --compile --install-headers /root/PycharmProjects/net_cut/venv/include/site/python3<span class="hljs-number">.8</span>/netfilterqueue Check the logs <span class="hljs-keyword">for</span> full command output.
</code></pre><p>The error is quite long and I've included the entire error message so you could understand what went wrong. <br /></p>
<p>A very important skill to have as a programmer is the ability to read errors. Solving errors is equally important but I think being able to identify errors takes precedence here.
The solution lies within the error. If you're able to read the error you'll be able to find what caused it and debug it quicker and more efficiently. <br /></p>
<p>In our case,  you notice it says <code>Using legacy 'setup.py install' for netfilterqueue, since package 'wheel' is not installed.</code> and it continues installing the package.</p>
<p>1st thing to note down is that your system is missing the <code>wheel</code> package. <br />
Wheels are the newer standard of Python distribution. It replaces eggs.
You can read more about it <a target="_blank" href="https://pythonwheels.com/">here</a> and how it compares with eggs <a target="_blank" href="https://www.python.org/dev/peps/pep-0427/#comparison-to-egg">here</a>.
<br /></p>
<p>So you need to install wheels if pip is still not able to install using legacy 'setup.py'
You can install wheels using the command <br />
<code>pip install wheel</code> for Python 2 and <br />
<code>pip3 install wheel</code> for Python 3 <br /></p>
<p>After wheel is installed you can try to install the package again. <br />
<code>pip install netfilterqueue</code>for Python 2 and <br />
<code>pip3 install netfilterqueue</code>for Python 3 <br /></p>
<p><strong>If it is able to install the package then Congratulations! You did a great job!</strong></p>
<p><em>If however, it is not then keep reading:</em></p>
<p>Wheels did not work for you, you should read what the next error is.</p>
<p>It says <br /></p>
<p><code>DEPRECATION: The -b/--build/--build-dir/--build-directory option is deprecated. pip 20.3 will remove support for this functionality. A possible replacement is use the TMPDIR/TEMP/TMP environment variable, possibly combined with --no-clean. You can find discussion regarding this at https://github.com/pypa/pip/issues/8333.</code> <br /></p>
<p>which basically means <code>--build</code> is <a target="_blank" href="https://github.com/pypa/pip/issues/8333">deprecated</a> and if you read through the discussion it says the deprecation was eventually <a target="_blank" href="https://github.com/pypa/pip/pull/2062">reversed</a> so that ideally shouldn't cause an issue. But if the command still fails then you can go to <code>netfilterqueue</code> <a target="_blank" href="https://github.com/kti/python-netfilterqueue">Github</a> page, to check it's installation steps.</p>
<p>You can just clone the directory to your local system and run setup to install the package.</p>
<p>You especially need to make sure you have <code>ibnetfilter_queue</code> development files and its associated dependencies.</p>
<p>You can easily install/upgrade these using the command <br /> 
<code>apt-get install build-essential python-dev libnetfilter-queue-dev</code></p>
<p>Once done, You can now begin to clone the directory using the command <br />
<code>pip3 install -U git+https://github.com/kti/python-netfilterqueue</code></p>
<p>This command will clone and run the setup file as well.</p>
<p>If you however would like to do all the steps manually then you can use the following commands:</p>
<ul>
<li><p><code>git clone https://github.com/kti/python-netfilterqueue.git</code> <br />
This command will clone the remote directory from Github to your local system.</p>
</li>
<li><p><code>cd python-netfilterqueue</code> <br />
To go to the folder where it is cloned.</p>
</li>
<li><p><code>python setup.py install</code> <br />
To run the setup that installs netfilterqueue in your system.</p>
</li>
</ul>
<p>If you get an error like the below after 1st step like I did:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598458292000/s1UnAFIlG.png" alt="httpserror.PNG" /></p>
<p>Then that means you do not have <code>(lib)curl-devel</code> installed. This means that <code>git</code> could not find the <code>git-remote-http</code> executable in the executables directory.</p>
<p>You can run the following command to resolve that:</p>
<p><code>apt-get install libcurl4-openssl-dev</code></p>
<p>If still however git is not recognizing the remote helper for https, you can use the following command:</p>
<p><code>pip install -U git+git://github.com/kti/python-netfilterqueue</code> for Python 2
<code>pip3 install -U git+git://github.com/kti/python-netfilterqueue</code> for Python 3</p>
<p>Just replace <code>https</code> with <code>git</code> and it should work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598458587686/WSE4trE7W.jpeg" alt="success.jpg" /></p>
<p>After this long arduous process you should have successfully installed the package on your local system.</p>
<p><strong>Take some time out and appreciate your hard work, you did a great job!</strong> <br /></p>
<p><strong>
<em>Let me know in the comments below which of these solutions worked for you </em></strong></p>
<p>Hope you enjoyed this post! If you happen to like it, feel free to share. You can also follow me on <a target="_blank" href="https://twitter.com/JaluiSaurav">Twitter</a> on my coding journey.</p>
]]></content:encoded></item><item><title><![CDATA[How to enable root user in Kali 2020]]></title><description><![CDATA[Photo from Kali.org 
So you’ve installed Kali because you’re interested in Ethical Hacking. Maybe you’re just trying a new flavor of Linux. If you’ve used Kali before you’ll notice that when you enter root as username and toor as password, it no long...]]></description><link>https://sauravjalui.com/how-to-enable-root-user-in-kali-2020</link><guid isPermaLink="true">https://sauravjalui.com/how-to-enable-root-user-in-kali-2020</guid><category><![CDATA[Linux]]></category><category><![CDATA[terminal]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Saurav Jalui]]></dc:creator><pubDate>Mon, 24 Aug 2020 10:45:27 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598258042288/9Go1YkVWt.png" alt="non-root-default-kali-user.png" /> 
<em>Photo from <a target="_blank" href="https://www.kali.org/news/kali-default-non-root-user/">Kali.org</a> </em></p>
<p>So you’ve installed Kali because you’re interested in Ethical Hacking. Maybe you’re just trying a new flavor of Linux. If you’ve used Kali before you’ll notice that when you enter <code>root</code> as username and <code>toor</code> as password, it no longer accepts those credentials. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598261032096/14BxPZDyx.png" alt="kalirootlogin.PNG" /></p>
<p>Kali will be running as user <code>Kali</code> with password as <code>Kali</code>.</p>
<p>From <strong>2020.1</strong> version, Kali Linux moved to <em> <strong>default non-root user.</strong> </em> This doesn’t mean that there is no root user or the password <code>toor</code> is incorrect. It's just that there is no default password set for root user.</p>
<h3 id="what-does-this-mean-and-what-are-some-ways-around-it">What does this mean and what are some ways around it?</h3>
<p>In the earlier days, many applications on Kali needed root user permission to run. Think of this like having to <strong>"Run as Administrator"</strong> while using Windows.
As time passed and Kali grew, a lot of users started using Kali as their primary OS. And when they do so they don't run as root user by default. So Kali concluded there is no need for a default root user and dropped it.</p>
<p><a target="_blank" href="https://www.kali.org/news/kali-default-non-root-user/">This article</a> talks more in detail about their reasoning behind this decision and next steps.</p>
<p>According to <a target="_blank" href="https://www.kali.org/news/kali-default-non-root-user/">Kali</a>, you can do the following if you would like to go back to the default root user mode:</p>
<ul>
<li><p>Login to Kali as user Kali [username <code>Kali</code> and password <code>Kali</code>].
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598260831328/f-tIIiwCY.jpeg" alt="kalilogin.jpg" /></p>
</li>
<li><p>Try running the command <code>apt-get update</code> in terminal without the sudo command. It'll throw the following error since you do not have root permissions:</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598264493519/X2rDJmiX_.png" alt="kaliapt.PNG" /></p>
<ul>
<li>Run the command <code>sudo dpkg-reconfigure kali-grant-root</code> in terminal to reconfigure password-less root rights. </li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598261714904/Cwp7mOhdQ.png" alt="kalisudo.PNG" /></p>
<ul>
<li>After clicking enter you'll see the following menu:</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598263174494/rm52FNhIS.png" alt="kalipackagebefore.PNG" /></p>
<p>Notice user <code>Kali</code> is not part of the trusted group, We need to add Kali to the trusted group.</p>
<ul>
<li>Click on <code>Enable password-less privilege escalation</code></li>
</ul>
<p>You should see the following commands:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598263269493/zwZKF2TQa.png" alt="kaliaddedtrusted.PNG" /></p>
<ul>
<li><p>Which means user <code>Kali</code> has now been added to trusted user group and thus shall not require password to access root rights.</p>
</li>
<li><p>If you run the command <code>sudo dpkg-reconfigure kali-grant-root</code> again, it should show user <code>Kali</code>in trusted user group.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598263281023/qVjnyf3GN.png" alt="kalipackage.PNG" /></p>
<p><strong>This however did not work for me for some reason.</strong></p>
<p>I decided to change the password of root instead, and that worked!</p>
<p>Steps to change the root password.</p>
<ul>
<li><p>Open Terminal and type the command <code>sudo su</code>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598263716172/kc-Ap2LFq.png" alt="sudo su.PNG" /></p>
</li>
<li><p>Then type in the command <code>passwd root</code>. This is the command to reset root password. Type in the new password and the password will be changed successfully!</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598263812964/hzNgU_932.png" alt="passwdroot.PNG" /></p>
<ul>
<li>Now that you've changed the root password, logout as user <code>Kali</code> and login as user <code>root</code> with the password you set in the previous step.</li>
</ul>
<p><strong> Congratulations! You're now logged in as root user.</strong></p>
<p>You can verify by trying the <code>apt-get update</code>command.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1598265163691/vyuk0iNYw.png" alt="kalirootupdate.PNG" /></p>
<p><strong>Let me know in the comments below which method worked for you. </strong></p>
]]></content:encoded></item></channel></rss>