<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adejumo Ridwan Suleiman</title>
    <description>The latest articles on DEV Community by Adejumo Ridwan Suleiman (@adejumoridwan).</description>
    <link>https://dev.to/adejumoridwan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1086085%2F76ccfad1-a58c-4875-8ade-3e3a8693fde7.jpeg</url>
      <title>DEV Community: Adejumo Ridwan Suleiman</title>
      <link>https://dev.to/adejumoridwan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adejumoridwan"/>
    <language>en</language>
    <item>
      <title>Build a Serverless Database for an SMS Spam Classifier with FaunaDB and FastAPI.</title>
      <dc:creator>Adejumo Ridwan Suleiman</dc:creator>
      <pubDate>Fri, 23 Jun 2023 08:09:55 +0000</pubDate>
      <link>https://dev.to/adejumoridwan/build-a-serverless-database-for-an-sms-spam-classifier-with-faunadb-and-fastapi-5268</link>
      <guid>https://dev.to/adejumoridwan/build-a-serverless-database-for-an-sms-spam-classifier-with-faunadb-and-fastapi-5268</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;A serverless database is a database that is hosted and managed by a third-party provider. This means you do not need to worry about the hardware, software, or maintenance of the database. You can simply connect to the database and start using it.&lt;/p&gt;

&lt;p&gt;Serverless databases are a good option for businesses that do not have the resources to manage their database. They are also a good option for businesses that need to scale their database quickly. Such examples of serverless databases are FaunaDB, CockroachDB, Amazon DynamoDB, and so on.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how to build a serverless database to store SMS messages sent to your WhatsApp number, and also their classification, if they are spam or not. You will use Twilio MessagingX SMS API to receive SMS messages on your Fast API backend which will send these data into FaunaDB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Python 3.9+ is installed on your machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FaunaDB free account, if you dont have one, you can set it up &lt;a href="https://fauna.com/"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Twilio free account, you can set up one &lt;a href="https://www.twilio.com/en-us"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ngrok account, follow this &lt;a href="https://www.twilio.com/blog/using-ngrok-2022"&gt;guide&lt;/a&gt; to set up one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An IDE or text editor, such as &lt;a href="https://code.visualstudio.com/"&gt;VS code&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hugging Face account, you can set one up &lt;a href="https://huggingface.co/login"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up the Development Environment
&lt;/h3&gt;

&lt;p&gt;Before you start, you need to set up the development environment by creating the directory and files you will need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir sms_classifier
cd sms_classifier
touch requirements.txt models.py utils.py main.py .env

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;requirements.txt&lt;/em&gt; contains the required libraries to build the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://model.py"&gt;&lt;em&gt;model.py&lt;/em&gt;&lt;/a&gt; contains the code connecting the Fast API app to FaunaDB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://utils.py"&gt;&lt;em&gt;utils.py&lt;/em&gt;&lt;/a&gt; contains the code to connect to the sms classification model on Hugging Face.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://main.py"&gt;&lt;em&gt;main.py&lt;/em&gt;&lt;/a&gt; contains the code to build the Fast API server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;sms_classifier&lt;/em&gt; is the directory for all our files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, you create and activate a virtual environment and update the Python package manager pip to the most recent version, to know more about the benefits of using virtual environments. Ensure you read this &lt;a href="https://linuxhostsupport.com/blog/why-using-a-python-virtual-environment-is-a-good-choice/#:~:text=Virtual%20environments%20are%20of%20great,the%20help%20of%20virtual%20environments."&gt;post&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m venv venv; ./venv/Scripts/Activate; pip - upgrade pip

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

&lt;/div&gt;



&lt;p&gt;If you are on a Linux machine use,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pyton -m venv venv; venv\\Scripts\\activate.bat; pip - upgrade pip

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

&lt;/div&gt;



&lt;p&gt;Next, fill the &lt;em&gt;requirements.txt&lt;/em&gt; file with the following dependencies,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastapi
uvicorn
faunadb
pyngrok
requests
dotenv

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;fastapi&lt;/code&gt; is a Python framework for building APIs quickly and easily&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;uvicorn&lt;/code&gt; is a lightning-fast server implementation for Python&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pyngrok&lt;/code&gt; enables you to tunnel a local server to a public URL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;requests&lt;/code&gt; allows you to send HTTP requests using Python&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;dotenv&lt;/code&gt; loads the environment variables from the &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;faunadb&lt;/code&gt; is a Python driver allowing you to connect to the fauna server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install these dependencies by running the following command on your terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -r requirements.txt

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connecting to Fauna Database
&lt;/h3&gt;

&lt;p&gt;On the Fauna home page, click on &lt;strong&gt;&lt;em&gt;Create Database&lt;/em&gt;&lt;/strong&gt; ,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E-iOW-t6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AChbIgopcy1tJmy4F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E-iOW-t6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AChbIgopcy1tJmy4F" alt="create a fauna db" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, give the name of your database, which is &lt;strong&gt;&lt;em&gt;SMS,&lt;/em&gt;&lt;/strong&gt; and select a &lt;strong&gt;&lt;em&gt;Region Group&lt;/em&gt;&lt;/strong&gt; then click &lt;strong&gt;&lt;em&gt;Create&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A-TXiupc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A23R1LQwOJTPqa5Qm" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A-TXiupc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A23R1LQwOJTPqa5Qm" alt="create a database collection" width="696" height="759"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;strong&gt;&lt;em&gt;Security&lt;/em&gt;&lt;/strong&gt; and click on &lt;strong&gt;&lt;em&gt;New Key&lt;/em&gt;&lt;/strong&gt; to create your fauna key&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3sBPx8jP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2Axvo9fRcYSjnePQ_U" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3sBPx8jP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2Axvo9fRcYSjnePQ_U" alt="get a fauna key" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the role as &lt;strong&gt;Server&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Save&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KdU_vGUK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A1wtRrUX9BmkHWmQ0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KdU_vGUK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A1wtRrUX9BmkHWmQ0" alt="creating the fauna key" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the fauna key displayed to you, then go to the &lt;em&gt;.env&lt;/em&gt; file and create a variable called &lt;code&gt;FAUNA_SECRET&lt;/code&gt; and paste it there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAUNA_SECRET=&amp;lt;secret&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Go to the &lt;a href="http://models.py"&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/a&gt; and paste the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from faunadb import query as q
from faunadb.client import FaunaClient
from dotenv import load_dotenv
import os

load_dotenv()

client = FaunaClient(secret=os.getenv("FAUNA_SECRET"),
endpoint="https://db.us.fauna.com/")
collection_name = "sms"

# Check if collection exists
try:
  client.query(q.get(q.collection(collection_name)))
  print(f"Collection '{collection_name}' already exists.")
except:
  # Collection doesn't exist, create it
  client.query(q.create_collection({"name": collection_name}))
  print(f"Collection '{collection_name}' created successfully.")

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;load_dotenv()&lt;/code&gt; loads the environment variables into &lt;a href="http://models.py"&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;FaunaClient()&lt;/code&gt; function is used to create a client object that can be used to interact with the FaunaDB database. It creates a fauna client using the secret key and fauna endpoint.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;collection_name&lt;/code&gt; stores the name of the collection, &lt;code&gt;q.get&lt;/code&gt; checks if a collection with the name &lt;code&gt;sms&lt;/code&gt; exists, and if false, &lt;code&gt;client.query&lt;/code&gt; creates a new collection &lt;code&gt;sms&lt;/code&gt;, collections are like tables in SQL.&lt;/p&gt;

&lt;p&gt;Run the code above and go back to the database you created earlier on. You will see the already created collection &lt;code&gt;sms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wCwSrSEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AlRCheIv0czP8mUQh" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wCwSrSEk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AlRCheIv0czP8mUQh" alt="view of the sms collection" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The dashboard shows no document in the collection, documents are NoSQL versions of rows in tables. Each SMS and its data will make up a document in the SMS collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the Spam Classifier Model Function
&lt;/h3&gt;

&lt;p&gt;An SMS spam classifier classifies an SMS as spam or ham (not spam). One can build a spam classifier from scratch, but this needs a lot of data and computing resources to get an accurate model. You are going to set up a hugging face account and use an already pre-built model from hugging face. Thanks to hugging face, you dont need to build an SMS spam classifier from scratch.&lt;/p&gt;

&lt;p&gt;To get a Hugging Face API key, go to &lt;strong&gt;&lt;em&gt;Settings&lt;/em&gt;&lt;/strong&gt; and click on &lt;strong&gt;&lt;em&gt;Access Tokens&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ULU4xjHt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AAw0ZBTo-xYgp1cnZ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ULU4xjHt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AAw0ZBTo-xYgp1cnZ" alt="get hugging face key" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new token with &lt;strong&gt;&lt;em&gt;READ&lt;/em&gt;&lt;/strong&gt; role by clicking on &lt;strong&gt;&lt;em&gt;New Token&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mkGsvUtv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A1xEuH9n5IQByrm8e" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mkGsvUtv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A1xEuH9n5IQByrm8e" alt="setting hugging face key to read" width="651" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this token and paste it to the &lt;em&gt;.env&lt;/em&gt; file, and store it as &lt;code&gt;HUGGING_API_KEY&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HUGGING_API_KEY="&amp;lt;api_key&amp;gt;"
FAUNA_SECRET="&amp;lt;fauna_secret&amp;gt;"

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

&lt;/div&gt;



&lt;p&gt;Copy and paste the following code below into &lt;a href="http://utils.py"&gt;&lt;em&gt;utils.py&lt;/em&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from dotenv import load_dotenv
import os
import requests
load_dotenv()
api_key=os.getenv("API_KEY")
# SMS Classification
def sms_spam_class(sms):
  API_URL = "https://api-inference.huggingface.co/models/mrm8488/bert-tiny-finetuned-sms-spam-detection"
  headers = {"Authorization": f"Bearer {api_key}"}
  def query(payload):
    response = requests.post(API_URL, headers=headers, json=payload)
    return response.json()
  output = query({
    "inputs": "f{sms}",
  })
  # Find the scores for 'LABEL_0' and 'LABEL_1'
  label_0_score = None
  label_1_score = None
  for item in output[0]:
    if item['label'] == 'LABEL_0':
      label_0_score = item['score']
    elif item['label'] == 'LABEL_1':
      label_1_score = item['score']
  # Check if 'LABEL_1' score is greater than 'LABEL_0' score
  if label_1_score is not None and label_0_score is not None:
    if label_1_score &amp;gt; label_0_score:
      spam_class = "spam"
      else:
      spam_class = "ham"
    else:
      spam_class = "Unable to determine spam status."
    return spam_class

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sms_spam_class()&lt;/code&gt; function checks if a given sms is spam or not, &lt;code&gt;API_URL&lt;/code&gt; contains the reference link to the spam classification model API. The headers contain the Hugging Face &lt;code&gt;api_key&lt;/code&gt; which allows you to make requests from the API using the requests library.&lt;/p&gt;

&lt;p&gt;The function &lt;code&gt;query()&lt;/code&gt; takes in the &lt;code&gt;payload&lt;/code&gt; which is &lt;code&gt;sms.&lt;/code&gt; This function makes a POST request using the &lt;a href="http://requests.post"&gt;&lt;code&gt;requests.post&lt;/code&gt;&lt;/a&gt; function and returns a JSON response &lt;code&gt;response.json()&lt;/code&gt; stored in the variable output.&lt;/p&gt;

&lt;p&gt;The output contains the score of the word for various labels, the &lt;code&gt;for&lt;/code&gt; loop checks each label score and stores the values into their respective variables, &lt;code&gt;label_0_score&lt;/code&gt; and &lt;code&gt;label_1_score&lt;/code&gt; for &lt;code&gt;Label_0&lt;/code&gt; and &lt;code&gt;Label_1&lt;/code&gt; respectively. &lt;code&gt;Label_0&lt;/code&gt; shows an SMS as ham (not spam) while &lt;code&gt;Label_1&lt;/code&gt; shows an SMS as spam.&lt;/p&gt;

&lt;p&gt;If the score in &lt;code&gt;Label_0&lt;/code&gt; is greater than &lt;code&gt;Label_1&lt;/code&gt; then the SMS is &lt;strong&gt;&lt;em&gt;spam&lt;/em&gt;&lt;/strong&gt; else the SMS is &lt;strong&gt;&lt;em&gt;ham&lt;/em&gt;&lt;/strong&gt; , and it saves the resulting classification in &lt;code&gt;spam_class.&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the webhook with ngrok
&lt;/h3&gt;

&lt;p&gt;Inside the &lt;a href="http://main.py"&gt;&lt;em&gt;main.py&lt;/em&gt;&lt;/a&gt;, set up a basic Fast API application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def index():
  return {"message": "I love Serverless"}

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

&lt;/div&gt;



&lt;p&gt;The code below sets up a basic &lt;code&gt;fastapi&lt;/code&gt; backend, creating a new instance of the Fast API class and assigning it to the &lt;code&gt;app&lt;/code&gt; variable. The &lt;code&gt;@app.get&lt;/code&gt; decorator creates a new endpoint that you can access with an HTTP GET request. The endpoint is at the root URL / and returns a JSON response with a single key-value pair: &lt;code&gt;message: I love Serverless.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To run the app, run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uvicorn main:appreload

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

&lt;/div&gt;



&lt;p&gt;On your browser, open the host &lt;a href="http://127.0.0.1:8000"&gt;http://127.0.0.1:8000&lt;/a&gt;&lt;a href="http://127.0.0.1:8000,"&gt;,&lt;/a&gt; you will see a JSON response of &lt;code&gt;{message: I love Serverless}&lt;/code&gt;, you can also access an interactive API doc provided by swagger on the host &lt;a href="http://127.0.0.1:8000/doc"&gt;http://127.0.0.1:8000/doc&lt;/a&gt; which allows you to interact with your API and see if you have any errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P2pCMTjk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A2zLG4li50ZDNfEes" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P2pCMTjk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A2zLG4li50ZDNfEes" alt="" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To receive Twilio messages on the backend, you are going to use &lt;code&gt;ngrok&lt;/code&gt; to host the local host on a public server. Read this &lt;a href="https://www.twilio.com/blog/using-ngrok-2022#:~:text=Open%20a%20terminal%20window%20and,under%20your%20account%2C%20without%20restrictions."&gt;post&lt;/a&gt; to learn how to set up &lt;code&gt;ngrok&lt;/code&gt; on your machine.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;ngrok&lt;/code&gt; administrator, run the command &lt;code&gt;ngrok http 8000&lt;/code&gt;, this makes your host public and you can receive messages on your backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OExBwrN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AxkSPw3qU0i0Ms4Yf" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OExBwrN7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AxkSPw3qU0i0Ms4Yf" alt="" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Log in to &lt;a href="https://www.twilio.com/user/account/two-factor/verify"&gt;Twilio Studio&lt;/a&gt;, under &lt;strong&gt;&lt;em&gt;Phone Numbers&lt;/em&gt;&lt;/strong&gt; go to &lt;strong&gt;&lt;em&gt;Manage&lt;/em&gt;&lt;/strong&gt; then &lt;strong&gt;&lt;em&gt;Buy a Number&lt;/em&gt;&lt;/strong&gt; to buy a Twilio Number.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RJ6c1VHS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AmeF4-0ydvj7zLTPD" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RJ6c1VHS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AmeF4-0ydvj7zLTPD" alt="buy a twilio number" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, go to &lt;strong&gt;&lt;em&gt;Active Numbers&lt;/em&gt;&lt;/strong&gt; to see your number, and click on the number. On the dashboard displayed to you, click on &lt;strong&gt;&lt;em&gt;Configure&lt;/em&gt;&lt;/strong&gt; and go to &lt;strong&gt;&lt;em&gt;Message Configuration&lt;/em&gt;&lt;/strong&gt; , paste the &lt;code&gt;ngrok&lt;/code&gt; address into the URL under &lt;strong&gt;&lt;em&gt;When a message comes in&lt;/em&gt;&lt;/strong&gt; and click &lt;strong&gt;&lt;em&gt;Save configuration&lt;/em&gt;&lt;/strong&gt; , this allows Twilio to request your fast API app anytime you receive an incoming message, congratulations you just set up a Webhook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dheh9urY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2Ada6BphV9SekRWEIp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dheh9urY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2Ada6BphV9SekRWEIp" alt="set up a twilio webhook" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the Fast API Application
&lt;/h3&gt;

&lt;p&gt;Update the &lt;a href="http://main.py"&gt;&lt;em&gt;main.py&lt;/em&gt;&lt;/a&gt; with the code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from fastapi import FastAPI, Form, Request
from utils import sms_spam_class
from dotenv import load_dotenv
import os
from faunadb import query as q
from model import client
load_dotenv()
app = FastAPI()
@app.post("/sms")
async def reply(request: Request):
  form_data = await request.form()

  MessageSid = form_data["MessageSid"]
  AccountSid = form_data["AccountSid"]
  From = form_data["From"]
  Body = form_data["Body"]
  To = form_data["To"]

  spam_class = sms_spam_class(Body)

  response = client.query(q.create(q.collection("sms"), {"data": {
    "MessageSid": MessageSid,
    "AccountSid": AccountSid,
    "From": From,
    "Body": Body,
    "To": To,
    "spam_classification": spam_class
  }}))
  return ""

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

&lt;/div&gt;



&lt;p&gt;The code above sends a POST request at the endpoint &lt;code&gt;/sms&lt;/code&gt;, the reply function takes the Twilio request as the query parameter. This will give us information on what and what was in the message you receive on your Twilio number.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;await request.form()&lt;/code&gt; stores the message data into &lt;code&gt;form_data&lt;/code&gt;, there are a lot of parameters when Twilio requests your webhook URL.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will just make use of some of the parameters. You can explore other parameters in their &lt;a href="https://www.twilio.com/docs/messaging/guides/webhook-request"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;MessageSid&lt;/code&gt; is a unique identifier assigned to every message&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;AccountSid&lt;/code&gt; is a unique identifier assigned to every Twilio account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;From&lt;/code&gt; is the phone number sending the message&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;To&lt;/code&gt; is the phone number receiving the message&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Body&lt;/code&gt; is the body of the SMS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sms_spam_class(Body)&lt;/code&gt; is the function you built earlier on classifying if a model is spam or not, storing the value in &lt;code&gt;spam_class&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The response variable stores all the parameters gotten from the SMS data in the database collection SMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the Server up and running
&lt;/h3&gt;

&lt;p&gt;Now your fast API app is ready to receive and store messages in the fauna database,&lt;/p&gt;

&lt;p&gt;Here is an example of an SMS sent to a Twilio number:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F5mZlpsg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AICRiVwrbSjYedFaF" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F5mZlpsg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2AICRiVwrbSjYedFaF" alt="sample sending sms" width="720" height="758"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Fauna, you will see the text messages reflected as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ZsyiMIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A7HRW-IcmKih3gkWv" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ZsyiMIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1320/0%2A7HRW-IcmKih3gkWv" alt="fauna database showing sms messages" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this tutorial, you learned how to create a Fauna serverless database that stores SMS messages and also their spam classification built on Fast API. You also learned about how to connect to pre-built models on Hugging Face.&lt;/p&gt;

&lt;p&gt;You can extend this app by adding more parameters from the Twilio request made to your webhook such as media URL, date a message was sent and received, and so on.&lt;/p&gt;

&lt;p&gt;You can also try another serverless database like Cassandra, Redis, MongoDB and so on.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>9 Things You Do That Shows You Are Not A Professional Python Developer</title>
      <dc:creator>Adejumo Ridwan Suleiman</dc:creator>
      <pubDate>Thu, 01 Jun 2023 13:24:01 +0000</pubDate>
      <link>https://dev.to/adejumoridwan/9-things-you-do-that-shows-you-are-not-a-professional-python-developer-44hn</link>
      <guid>https://dev.to/adejumoridwan/9-things-you-do-that-shows-you-are-not-a-professional-python-developer-44hn</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kxvrubMj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1200/0%2A9nsiWRvRtlKCjNmH" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kxvrubMj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1200/0%2A9nsiWRvRtlKCjNmH" alt="" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@timothycdykes?utm_source=medium&amp;amp;utm_medium=referral"&gt;Timothy Dykes&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Show me your code and I will tell you who you are.&lt;/p&gt;

&lt;p&gt;This article will fix the bad habits you have stuck to over the years or brought from other programming languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual String Formatting
&lt;/h3&gt;

&lt;p&gt;Most of the time you see beginner Pythonistas using the &lt;code&gt;+&lt;/code&gt; sign when combining two strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; name = "Ridwan"
&amp;gt;&amp;gt;&amp;gt; age = "22"
&amp;gt;&amp;gt;&amp;gt; print("My Name is " + name + " and I am " + age + " years old")
My Name is Ridwan and I am 22 years old

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

&lt;/div&gt;



&lt;p&gt;Instead of using the &lt;code&gt;+&lt;/code&gt; sign, use the &lt;code&gt;f&lt;/code&gt; string which makes your code readable, concise, and less prone to errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print(f"My Name is {name} and I am {age} years old")
My Name is Ridwan and I am 22 years old

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Default Mutable Arguments
&lt;/h3&gt;

&lt;p&gt;In Python, anytime you pass a mutable value as an argument in a function, the default argument is mutated anytime the function is called. These mutable arguments are usually lists or dictionaries.&lt;/p&gt;

&lt;p&gt;Look at the example below;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; def append(n, l=[]):
... l.append(n)
... return l
...

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

&lt;/div&gt;



&lt;p&gt;After defining the append function with a mutable argument &lt;code&gt;l = []&lt;/code&gt;, anytime you call the function with a value of &lt;code&gt;n&lt;/code&gt;, it changes the default value of &lt;code&gt;l&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; l1 = append(0)
&amp;gt;&amp;gt;&amp;gt; l1
[0]

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

&lt;/div&gt;



&lt;p&gt;When next you call the function with a different value of &lt;code&gt;n&lt;/code&gt;, you are going to see the previous value you used appended to the empty list argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; l2 = append(1)
&amp;gt;&amp;gt;&amp;gt; l2
[0, 1]

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

&lt;/div&gt;



&lt;p&gt;You can solve this problem by rewriting the code as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; def append(n, l = None):
... if l is None:
... l = []
... l.append(n)
... return l
...
&amp;gt;&amp;gt;&amp;gt; l1 = append = [0]
&amp;gt;&amp;gt;&amp;gt; l2 = append = [1]
&amp;gt;&amp;gt;&amp;gt; l1,l2
([0], [1])

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

&lt;/div&gt;



&lt;p&gt;Now the argument &lt;code&gt;l&lt;/code&gt; is set to &lt;code&gt;None&lt;/code&gt;, anytime the function is called even if &lt;code&gt;l&lt;/code&gt; is mutated, it is reassigned as &lt;code&gt;None&lt;/code&gt; and then given the value of an empty list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Using Comprehensions
&lt;/h3&gt;

&lt;p&gt;Python comprehensions provides you a short and concise way of way of constructing sequences, last time I checked, Python supports 4 types of comprehension;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;List Comprehensions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dictionary Comprehensions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set Comprehensions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generator Comprehensions&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read more about them &lt;a href="https://www.geeksforgeeks.org/comprehensions-in-python/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code below divides the values in a dictionary by 2,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; numbers = {}
&amp;gt;&amp;gt;&amp;gt; for i in range(10):
... numbers[i] = i/2
...
&amp;gt;&amp;gt;&amp;gt; numbers
{0: 0.0, 1: 0.5, 2: 1.0, 3: 1.5, 4: 2.0, 5: 2.5, 6: 3.0, 7: 
3.5, 8: 4.0, 9: 4.5}

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

&lt;/div&gt;



&lt;p&gt;The above code can be written in a single line as,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; {i: i/2 for i in range(10)}
{0: 0.0, 1: 0.5, 2: 1.0, 3: 1.5, 4: 2.0, 5: 2.5, 6: 3.0, 7: 
3.5, 8: 4.0, 9: 4.5}

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

&lt;/div&gt;



&lt;p&gt;So stop making life difficult for yourself and start using comprehension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking for Equality instead of Identity
&lt;/h3&gt;

&lt;p&gt;Given,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = [1, 2, 3]
b = [1, 2, 3]

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

&lt;/div&gt;



&lt;p&gt;If I ask you to check if the two variables are identical, the first thing to come to your mind is,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a == b
True

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

&lt;/div&gt;



&lt;p&gt;The thing is that you need to know the difference between &lt;em&gt;Identity&lt;/em&gt; and &lt;em&gt;Equality&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Two variables can be equal but not identical.&lt;/p&gt;

&lt;p&gt;If you check the memory addresses of a and b,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; id(a), id(b)
(1838093945856, 1838093487488)

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

&lt;/div&gt;



&lt;p&gt;You can see that they both have different addresses despite the fact that they have the same object.&lt;/p&gt;

&lt;p&gt;This is the reason why, when you run,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a == b
True

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

&lt;/div&gt;



&lt;p&gt;You get &lt;code&gt;True&lt;/code&gt;, but when you run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a is b
False

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

&lt;/div&gt;



&lt;p&gt;You get &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are equal but not identical.&lt;/p&gt;

&lt;p&gt;In the case where you have,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; c = [1,2,3]
&amp;gt;&amp;gt;&amp;gt; d = c
&amp;gt;&amp;gt;&amp;gt; id(c), id(d)
(1838089019712, 1838089019712)

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

&lt;/div&gt;



&lt;p&gt;You can see, &lt;code&gt;c&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt; are both equal and identical, the object in &lt;code&gt;c&lt;/code&gt; is also assigned to &lt;code&gt;d&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; c == d
True
&amp;gt;&amp;gt;&amp;gt; c is d
True

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

&lt;/div&gt;



&lt;p&gt;This implies &lt;code&gt;c&lt;/code&gt; and &lt;code&gt;d&lt;/code&gt; have both the same value and memory addresses.&lt;/p&gt;

&lt;p&gt;Hence you can say &lt;code&gt;c&lt;/code&gt; is identical and equal to &lt;code&gt;d&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All this epistle is to make you know the difference between &lt;code&gt;is&lt;/code&gt; and &lt;code&gt;==&lt;/code&gt;, the former is used in checking identity while the latter is used in checking equality.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All Identical variables are equal but not all Equal variables are identical&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Not Using Tuple Unpacking
&lt;/h3&gt;

&lt;p&gt;Anytime you create a tuple in Python, it is known as &lt;em&gt;packing a tuple&lt;/em&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a_tuple = 1,2,3
&amp;gt;&amp;gt;&amp;gt; a_tuple
(1, 2, 3)

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

&lt;/div&gt;



&lt;p&gt;These values can be extracted back into various variables by unpacking&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; x = a_tuple[0]
&amp;gt;&amp;gt;&amp;gt; y = a_tuple[1]
&amp;gt;&amp;gt;&amp;gt; z = a_tuple[2]
&amp;gt;&amp;gt;&amp;gt; print(x, y, z)
1, 2, 3

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

&lt;/div&gt;



&lt;p&gt;Instead of unpacking the elements in a tuple using multiple lines of code, you can do it in a single line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; x,y,z = a_tuple
&amp;gt;&amp;gt;&amp;gt; print(x, y, z)
1, 2, 3

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating Your Own Index Counter Variable
&lt;/h3&gt;

&lt;p&gt;This one is common from those coming from other programming languages, you are asked to create a index counter variable and you type something like;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a_list = [1,2,3,4,5,6,7,8,9,10]
&amp;gt;&amp;gt;&amp;gt; index = 0
&amp;gt;&amp;gt;&amp;gt; for elem in a_list:
... print(index, elem)
... index += 1
...
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

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

&lt;/div&gt;



&lt;p&gt;Instead, use the enumerate function to make your code look Pythonic;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; for index, elem in enumerate(a_list):
... print(index, elem)
...
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Print Statement Instead of the Logging Module
&lt;/h3&gt;

&lt;p&gt;This might not matter in small projects, but will surely help you in larger projects.&lt;/p&gt;

&lt;p&gt;Instead of littering your code with print statements, use the logging instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print('This is a warning message')
This is a warning message
&amp;gt;&amp;gt;&amp;gt; print('This is an error message')
This is an error message
&amp;gt;&amp;gt;&amp;gt; print('This is a critical message')
This is a critical message

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

&lt;/div&gt;



&lt;p&gt;Logging helps display useful messages to your users to add more context and understanding to what is happening in the code base.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; import logging
&amp;gt;&amp;gt;&amp;gt; logging.warning('This is a warning message')
WARNING:root:This is a warning message
&amp;gt;&amp;gt;&amp;gt; logging.error('This is an error message')
ERROR:root:This is an error message
&amp;gt;&amp;gt;&amp;gt; logging.critical('This is a critical message')
CRITICAL:root:This is a critical message

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Importing functions and classes in a named module with import *
&lt;/h3&gt;

&lt;p&gt;This bad habit most at times is common among newbies.&lt;/p&gt;

&lt;p&gt;Importing using &lt;code&gt;import *&lt;/code&gt; corrupts your namespace by importing all the functions and classes from that named module into your code which is likely to conflict with the functions you define or functions of other libraries imported.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Following pep8
&lt;/h3&gt;

&lt;p&gt;Most of us are guilty of this,&lt;/p&gt;

&lt;p&gt;Before I get canceled 😂, I know some of my codes in this article might have broken the rules of PEP-8, but the truth is bitter and needs to be told, following PEP-8 style and guidelines makes it easier for others to read and understand your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Not Recommended&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; def function():
... x = [1,2,3]
... y= [2,3,5]
... z = [1, 2,3]
...
&amp;gt;&amp;gt;&amp;gt; def value(x = 7):
... ...
...

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Recommended&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; def function():
... x = [1, 2, 3]
... y = [2, 3, 5]
... z = [1, 2, 3]
...
&amp;gt;&amp;gt;&amp;gt; def number(x=7):
... ...
...

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

&lt;/div&gt;



&lt;p&gt;To read more about the PEP-8 style and guidelines, check out &lt;a href="https://realpython.com/python-pep8/"&gt;this article&lt;/a&gt;.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Thanks for reading. Hope the article was worth your time.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
  </channel>
</rss>
