<?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: salem ododa</title>
    <description>The latest articles on DEV Community by salem ododa (@salemzii).</description>
    <link>https://dev.to/salemzii</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%2F759196%2F010bd20c-e11c-499a-8aaa-f7dc734b05cc.jpg</url>
      <title>DEV Community: salem ododa</title>
      <link>https://dev.to/salemzii</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/salemzii"/>
    <language>en</language>
    <item>
      <title>Writing Custom Log Handlers In Python</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Wed, 02 Nov 2022 13:50:26 +0000</pubDate>
      <link>https://dev.to/salemzii/writing-custom-log-handlers-in-python-58bi</link>
      <guid>https://dev.to/salemzii/writing-custom-log-handlers-in-python-58bi</guid>
      <description>&lt;p&gt;Have you ever wondered how logging services like logz .io or loggly .com ship your logs, onto their platform? For example logz .io has an &lt;a href="https://github.com/logzio/logzio-python-handler" rel="noopener noreferrer"&gt;opensource&lt;/a&gt; logging handler which they use to transport logs from your application to their platform where further analysis are carried out on these logs to enable you derive substantial insights on your application's performance. In this short article we are briefly going to cover the basics of writting user-defined log handlers using the python &lt;a href="https://docs.python.org/3/library/logging.html" rel="noopener noreferrer"&gt;standard logging&lt;/a&gt; package. &lt;/p&gt;

&lt;p&gt;You might be wondering why i chose to write about this rather "odd" topic, but the importance of a good logging system cannot be overstated, whether your application is a web application, mobile  or even an operating system, logging enables you to derive useful informations on how your application is performing. A good logging system helps in catching errors as they happen, instead of relying on users to report them, the majority of whom simply wouldn’t or wouldn’t know how to do it. &lt;/p&gt;

&lt;h2&gt;
  
  
  The logging.StreamHandler
&lt;/h2&gt;

&lt;p&gt;The python standard logging package provides a &lt;strong&gt;Handler&lt;/strong&gt; class which basically defines how a particular log message is handled, we can configure a simple handler that prints log messages to the terminal like this: &lt;/p&gt;

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

LOGGING = {
    "version": 1, 
    "disable_existing_loggers": False,
    "formatters": {
        "stdformatter": {"format": "DateTime=%(asctime)s loglevel=%(levelname)-6s  %(funcName)s() L%(lineno)-4d %(message)s call_trace=%(pathname)s L%(lineno)-4d"},
    },
    "handlers": {
        "stdhandler": {
            "class": "logging.StreamHandler",
            "formatter": "stdformatter",
            'stream': 'ext://sys.stdout'
        },
    },
    "loggers" : {
        "root": {
            "handlers": ["stdhandler"], 
            "level": "DEBUG",
            "propagate": True
            }
        }
}


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

&lt;/div&gt;

&lt;p&gt;We can then initialize this configuration, in a log.py &lt;em&gt;assuming the log.py file is the application we want to log&lt;/em&gt;&lt;/p&gt;

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

import logging
from logging.config import dictConfig


dictConfig(LOGGING)
logger = logging.getLogger()
logger.debug("logger started")

def logToConsole():
    logger.info("Application started, succesfully")
    logger.info("Logging to the console")
    logger.info("Finished logging to console!")

# call the function
logToConsole()


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

&lt;/div&gt;

&lt;p&gt;When we run the log.py file &lt;code&gt;python3 log.py&lt;/code&gt;; we can see a similar output to this shown on the terminal&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh7ivkjvue766eejd0hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh7ivkjvue766eejd0hp.png" alt="Logging to the console with python"&gt;&lt;/a&gt;&lt;br&gt;
As you can see we've been able to configure a handler that logs directly to the console(stdout), keep in mind you don't need to create any congifuration to log to the terminal, since the StreamHandler is the default handler for the logging package. The logging package also comes with an array of already made &lt;strong&gt;Handlers&lt;/strong&gt; you can use asides the StreamHandler, some of which are listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FileHandler&lt;/strong&gt;: which sends logging output to a disk file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NullHandler&lt;/strong&gt;: It is essentially a ‘no-op’ handler for use by library developers. Which i've never had any reason to use :)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BaseRotatingHandler&lt;/strong&gt;: which is basically another type of FileHandler for special use cases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SocketHandler&lt;/strong&gt;: which sends logging output to a network socket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SysLogHandler&lt;/strong&gt;: which sends logging messages to a remote or local Unix syslog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SMTPHandler&lt;/strong&gt;: which sends log messages to an email address, using SMTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPHandler&lt;/strong&gt;: which supports sending logging messages to a web server, using either GET or POST semantics. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are several handlers provided by the logging package that can be found &lt;a href="https://docs.python.org/3/library/logging.handlers.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;, some of which you might never have a use case for since they are built for very specific use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Handlers
&lt;/h2&gt;

&lt;p&gt;Supposing we are building a cloud based logging as a service software like &lt;a href="https://logz.io" rel="noopener noreferrer"&gt;logz.io&lt;/a&gt;, where we'd like to store, retrieve and analyze our logs for better insights; python provides a low-level "api" to enable us transports logs from python applications easily, using the &lt;code&gt;logging.Handler&lt;/code&gt; class. In the following example we are going to create a simple Custom Handler that writes to a ".txt" file. Obviously log messages are not written to txt files but this is to illustrate how to write Custom Log Handlers in a simple way. &lt;/p&gt;

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

class SpecialHandler(logging.Handler):

    def __init__(self )-&amp;gt; None:
        self.sender = LogSender()
        logging.Handler.__init__(self=self)

    def emit(self, record) -&amp;gt; None:
        self.sender.writeLog(record)


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

&lt;/div&gt;

&lt;p&gt;In the code above we declare a class named &lt;code&gt;SpecialHandler&lt;/code&gt;, which inherits from the &lt;code&gt;logging.Handler&lt;/code&gt; base class, this basically allows us to extend the base Handler so as to make it fit our use. We then declare the &lt;code&gt;__init__&lt;/code&gt; method and initiates the class which handles each log record as it is retrieved i.e &lt;code&gt;LogSender&lt;/code&gt;, the &lt;code&gt;emit(self, record)&lt;/code&gt; method is quite special as it responsible for sending each log record to the specified reciever. &lt;/p&gt;

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

 class LogSender:
    def __init__(self) -&amp;gt; None:
        pass

    def writeLog(self, msg: logging.LogRecord) -&amp;gt; None:
        with open("application.txt",'a',encoding = 'utf-8') as f:
            f.write(f"{msg} \n")


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;LogSender&lt;/code&gt; class acts as the retriever of log records as they are sent from the &lt;code&gt;emit&lt;/code&gt; method of the Handler's class; the &lt;strong&gt;LogSender&lt;/strong&gt; class declares a &lt;code&gt;writeLog&lt;/code&gt; method, which accepts any argument of type &lt;code&gt;msg: logging.LogRecord&lt;/code&gt;. On reception of a record it opens a txt file &lt;code&gt;application.txt&lt;/code&gt; in append mode and writes the log message to the file, adding a new line at the end of it.&lt;br&gt;
This is basically all it takes to create a customHandler, we can configure our &lt;code&gt;LOGGING Dictionary&lt;/code&gt; to recognize this new handler with a few lines of code, like so:&lt;/p&gt;

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

LOGGING = {
    "version": 1, 
    "disable_existing_loggers": False,
    "formatters": {
        "stdformatter": {"format": "DateTime=%(asctime)s loglevel=%(levelname)-6s  %(funcName)s() L%(lineno)-4d %(message)s call_trace=%(pathname)s L%(lineno)-4d"},
    },
    "handlers": {
        "stdhandler": {
            "class": "logging.StreamHandler",
            "formatter": "stdformatter",
            'stream': 'ext://sys.stdout'
        },
        "specialhandler":{
            "class" : "writer.SpecialHandler",
            "formatter": "stdformatter",
        }
    },
    "loggers" : {
        "root": {
            "handlers": ["stdhandler", "specialhandler"], 
            "level": "DEBUG",
            "propagate": True
            }
        }
}


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

&lt;/div&gt;

&lt;p&gt;Keep in mind, the writer.SpecialHandler is our custom handler class written in a writer.py file. To initialize this changes we can import the writer.py file into our log.py file and load the logging configuration into dictConfig again, but this time with a custom handler that writes to our application.txt file. &lt;/p&gt;

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

import logging
from logging.config import dictConfig
import writer #writer.py contains our SpecialHandler and LogSender class respectively

LOGGING = {
    "version": 1, 
    "disable_existing_loggers": False,
    "formatters": {
        "stdformatter": {"format": "DateTime=%(asctime)s loglevel=%(levelname)-6s  %(funcName)s() L%(lineno)-4d %(message)s call_trace=%(pathname)s L%(lineno)-4d"},
    },
    "handlers": {
        "stdhandler": {
            "class": "logging.StreamHandler",
            "formatter": "stdformatter",
            'stream': 'ext://sys.stdout'
        },
        "specialhandler":{
            "class" : "writer.SpecialHandler",
            "formatter": "stdformatter",
        }
    },
    "loggers" : {
        "root": {
            "handlers": ["stdhandler", "specialhandler"], 
            "level": "DEBUG",
            "propagate": True
            }
        }
}

dictConfig(LOGGING)
logger = logging.getLogger()
logger.debug("logger started")

def logToConsole():
    logger.info("Application started, succesfully")
    logger.info("Logging to the console")
    logger.info("Finished logging to console!")

# call the function
logToConsole()


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

&lt;/div&gt;

&lt;p&gt;When we run &lt;code&gt;python3 log.py&lt;/code&gt; we can see an application.txt file is created within the current directory, containing all the log records. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgurb2uxxd5v4pw50xccn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgurb2uxxd5v4pw50xccn.png" alt="custom handler output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Logging applications can save us hours in debugging hidden bugs within our application, as well as enabling to derive useful insights about the performance, operatability and needs of applications without any hassles. In this short article, we've seen how to write basic custom log handlers for our applications, extending to fit our specific needs. &lt;/p&gt;

&lt;p&gt;Let me know what you think about this article and possibly any amendments that can be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>python</category>
      <category>logs</category>
      <category>microservices</category>
      <category>devops</category>
    </item>
    <item>
      <title>message brokers, a brief walk-through</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Mon, 12 Sep 2022 17:30:23 +0000</pubDate>
      <link>https://dev.to/salemzii/message-brokers-a-brief-walk-through-5h7f</link>
      <guid>https://dev.to/salemzii/message-brokers-a-brief-walk-through-5h7f</guid>
      <description>&lt;p&gt;In an ever changing world of software development,utilizing microservices and distributed systems is the &lt;code&gt;de facto&lt;/code&gt; standard for architecting software solutions, there is always a need to employ efficient means of message transfer between these various microservices. &lt;br&gt;
One of the fundamental aspect of developing these services infact, is to incorporate an &lt;code&gt;Inter-service&lt;/code&gt; communication between them. And although there are numerous methods of approaching this; &lt;code&gt;Message Brokers&lt;/code&gt; provide an efficient, scalable and cheaper means of data sharing betwixt these services. &lt;br&gt;
In this article we are briefly going to uncover the basics of message brokers, and build a distributed alert system that publishes alert messages to listed email addresses and a twitter account; using &lt;code&gt;fastapi&lt;/code&gt; &lt;code&gt;golang/gin&lt;/code&gt; and &lt;code&gt;rabbitmQ&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message Brokers
&lt;/h2&gt;

&lt;p&gt;A broker in layman's term is someone who negotiates/arranges a transaction between two entities (be it people, businesses e.t.c) similarly; Message brokers are an inter-service communication technology, that utilizes standard messaging protocols to promote rapid development, and data-sharing between distributed applications. Message brokers provide data-sharing, data-marshaling, and data persistences features to traditional middleware applications out of the box, and they as well guarantee the transfer of messages with low latency. They ensure delivery of messages even when a consumer(client) is inactive, this enhances reliability/uptime of  application's flow since each service is independent. A typical case for example is a service responsible for sending emails to recently signed up users, now assuming the service went down at the time a user is being registered, the downtime doesn't interupt the user's experience since the native backend only has to publish to the &lt;code&gt;sign-up queue&lt;/code&gt;, which the consuming application can process from whenever it is restored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishers, Consumers and Queues
&lt;/h2&gt;

&lt;p&gt;Message brokers primarily rely on three fundamental concepts for message transfer, they are &lt;code&gt;Publishers&lt;/code&gt;, &lt;code&gt;Consumers&lt;/code&gt; and &lt;code&gt;Queues&lt;/code&gt; and although they might differ in name and behaviour pending on the message brokers you use, they can still be used interchangably(or not) with &lt;code&gt;Producers&lt;/code&gt;, &lt;code&gt;Subscribers&lt;/code&gt; and &lt;code&gt;Channels&lt;/code&gt;; So lets have a brief walkthrough of each of these concepts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Publishers&lt;/code&gt;: In messaging, publishers (or producers) represents an application that sends/publishes messages to a message broker instance. Depending on the protocol, the publisher sends the message to a broker which further routes the message to the approriate queue/channel. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Consumers&lt;/code&gt;: consumers (or subscribers) represents application that readily listens on a queue or channel for new messages from the publisher. In order to consume messages, a consumer has to be registered to a queue.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Queues&lt;/code&gt;: queues as we know them are data structures that provides two kind of operations; &lt;code&gt;enqueue&lt;/code&gt; whereby data is enterred into the queue through the rear or tail, and &lt;code&gt;dequeue&lt;/code&gt; whereby data is removed from the queue through the front or head. In message brokers, queues are referenced via their names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Sharing
&lt;/h2&gt;

&lt;p&gt;Since the essence of this article revolves around data tranfer, i'd quickly like to deviate your attention to commonly employed design practices when defining how applications should communicate with each other.&lt;br&gt;
In the process of building a distributed system where message sharing is priority, you should be able to answer the following questions:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What data does your services need to share?&lt;/li&gt;
&lt;li&gt;What service(s) are the primary providers of the data, can they be identified?&lt;/li&gt;
&lt;li&gt;Does the nature of the data imply the introduction of a third-party software to share it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Answering these questions are quintessential to the development of solid distributed ecosystems. When we start to write the codes for this article, we'd incoporate this services and see if our solution answer these questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  When and Why Should We Use Message Brokers?
&lt;/h2&gt;

&lt;p&gt;Unlike the typical &lt;code&gt;client-server&lt;/code&gt; paradigm, where a client (eg. web browser) sends a requests to a server, and blocks till it gets a response back from the server, message brokers allows a client to continue with other operations, whilst it processes the former requests. This is incredible because it saves time, and enhances the user's experience; Imagine a scenerio where you have to successfully send a user their registration email, before redirecting them to their profile or the login page, the time spent waiting on the email service would imply a very poor user experience.&lt;br&gt;
Suffice to say it's best to use message brokers whenever you're  building something whose average processing time spans beyond the traditional http requests/responses duration. Keep in mind &lt;code&gt;time&lt;/code&gt; isn't the only yardstick to consider when trying out message brokers, but it is one to always have in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building an alert dispatch service
&lt;/h2&gt;

&lt;p&gt;Up until this point we've seen ideal situations where we would want to build our applications using message brokers. This section aims at furthering your practical knowledge on the use of message brokers, and we are going to be building an &lt;code&gt;Alert Dispatch Service&lt;/code&gt;, which is essentially an &lt;code&gt;API&lt;/code&gt; that recieves a json post request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vldwzebir5ip1h0q9r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vldwzebir5ip1h0q9r6.png" alt="json sample"&gt;&lt;/a&gt;&lt;br&gt;
the API then serializes this json and publishes it to a message broker (&lt;code&gt;RabbitMq&lt;/code&gt;) which in turn broadcasts it to any consumer listening on the queue, the consuming service serializes the recieved data and publishes the message to a twitter account and a list of email addresses. &lt;br&gt;
The Api is written in &lt;code&gt;python fastapi framework&lt;/code&gt; and the consumer is written in &lt;code&gt;golang&lt;/code&gt;, this example elaborates the use cases of message brokers as we can see how we've enabled communication between two independent  microservices, written in entirely different languages; whether this service has a use case in real world scenerios isn't considered as i only thought of a perfect example for using message brokers, which would be straight to beginners. &lt;/p&gt;

&lt;h2&gt;
  
  
  Fastapi Service (Publisher)
&lt;/h2&gt;

&lt;p&gt;As i mentioned earlier, the &lt;code&gt;Api&lt;/code&gt; and &lt;code&gt;publisher&lt;/code&gt; service is written with python's modern web api framework &lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;fastapi&lt;/a&gt;, it is quite easy to set up. First we need to set up our virtual environment, do this by running &lt;code&gt;python -m venv &amp;lt;name_of_your_virtual_env&amp;gt;&lt;/code&gt; you can activate your virtual environment on windows by running &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;name_of_venv&amp;gt;/bin/activate.bat&lt;/code&gt; or &lt;code&gt;source &amp;lt;name_of_venv&amp;gt;/bin/activate&lt;/code&gt; on linux/macOs. Next we need to install &lt;code&gt;fastapi&lt;/code&gt; by running:&lt;br&gt;
&lt;code&gt;pip install fastapi&lt;/code&gt; &lt;br&gt;
this installs fastapi, alongside other dependencies it needs to function properly. Then we need to install &lt;code&gt;uvicorn&lt;/code&gt; which will act as the ASGI (Asynchronous server gateway interface)  server for our application; to do this run &lt;code&gt;pip install uvicorn&lt;/code&gt;. Once you've completed this setups, we can move on to writing our codes;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42n10x6mwt8hyzkhnkxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42n10x6mwt8hyzkhnkxg.png" alt="Importing our dependencies and declaring the alert schema"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the code above,on line one and two we imported the &lt;code&gt;FastAPI&lt;/code&gt; class from fastapi and also the &lt;code&gt;BaseModel&lt;/code&gt; class from &lt;a href="https://pydantic-docs.helpmanual.io/" rel="noopener noreferrer"&gt;pydantic&lt;/a&gt;&lt;br&gt;
we then instantiate the fastapi class with a variable called app on line 4, we will see the use of this app variable shortly.On line 8 we create an Alert class which is the schema of the json data our api expects, and within the class we declare two fields, &lt;code&gt;topic&lt;/code&gt; which is the topic of the alert and &lt;code&gt;message&lt;/code&gt; which is the alert's content. Notice how our alert class inherits the &lt;code&gt;pydantic.BaseModel&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Next we write our api function on line 14, the &lt;code&gt;app&lt;/code&gt; variable defines the http method required by the function and also declares it's route, then the function basically checks if an http request body contain's an alert type, &lt;em&gt;notice how all the &lt;code&gt;Serialization&lt;/code&gt; is handled neatly by Fastapi behind the scenes&lt;/em&gt;; if the alert is valid we calls our rabbitmQ publisher function else, we throw an error at the client. The Publisher function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58iwy284rp8uqwjiwxvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58iwy284rp8uqwjiwxvn.png" alt="Publisher function"&gt;&lt;/a&gt;&lt;br&gt;
For the publisher, we import two packages &lt;code&gt;Pika&lt;/code&gt; which is a python library for communicating with rabbitmQ and &lt;code&gt;json&lt;/code&gt; to enable us serialize the alert instance. Then we create a connection to our rabbitmQ instance, and declare a &lt;code&gt;Queue&lt;/code&gt; named &lt;code&gt;alert_queue&lt;/code&gt;, when you declare a queue, rabbitmQ checks to see if the queue already exists, if it doesn't it creates the queue else it just goes ahead to publish the message. Next we declare a dictionary, to map our Alert's value, this is to enable us send messages in json format to our message broker, which can be delivered and serialized by our consumer service. Finally we publish the message to the &lt;code&gt;alert_queue&lt;/code&gt; and return from the function body. &lt;/p&gt;

&lt;h2&gt;
  
  
  Golang Service (Consumer)
&lt;/h2&gt;

&lt;p&gt;The consumer service is written in go, to elaborate the essence of this article i.e &lt;em&gt;using message brokers to transfer messages between different, independent microservices&lt;/em&gt;. &lt;br&gt;
Unfortunately i won't be able to detail the code bit by bit since this article is becoming too lengthy, but it's quite straight-forward if you write Go regularly;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyhqq2x8hculbtby3u3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyhqq2x8hculbtby3u3n.png" alt="connecting to rabbitmQ with go"&gt;&lt;/a&gt;&lt;br&gt;
Basically this code, connects to our rabbitmQ using the &lt;a href="https://github.com/streadway/amqp" rel="noopener noreferrer"&gt;streadway/amqp&lt;/a&gt; package which is the golang standard library for communicating with rabbitmQ, next we declare a unique channel to enable us pass across message to a specific queue. Then we call the &lt;code&gt;Consume&lt;/code&gt; function which takes in a parameter of &lt;code&gt;*amqp.Channel&lt;/code&gt; which is the channel we created previously. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8yc8f3c4rcyl2zqda2d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe8yc8f3c4rcyl2zqda2d.png" alt="consume message from the queue"&gt;&lt;/a&gt;&lt;br&gt;
So the &lt;code&gt;Consume&lt;/code&gt; function basically reads all the messages currently available in the queue and serializes them to an &lt;code&gt;alert&lt;/code&gt; variable, then it sends a tweet to a specified twitter account with the alert's message as the tweet's content, it also sends an email with the alert's topic as subject and the alert's message as the email's content to my email address. I'm obviously not gonna go into the details of how to programmatically create a tweet or send an email. But if you're interested in learning how to send &lt;strong&gt;Emails&lt;/strong&gt; with golang, you should definitely take look at my article &lt;a href="https://dev.to/salemzii/sending-e-mails-with-go-ff0"&gt;Sending E-mails with Go&lt;/a&gt;. All the sample codes written here are publicly available on this &lt;a href="https://github.com/salemzii/MQ-dispatcher" rel="noopener noreferrer"&gt;github&lt;/a&gt; repository with instructions to run them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Being able to effectively exchange messages across multiple decoupled software components is vital for every distributed ecosystem; message brokers provides an easy, scalable and reliable means of achieving this.&lt;br&gt;
In this article we've briefly covered the basics of publishing and consuming messages with rabbitmq, we went further to build an alert dispatch service that distributes alerts to listed email addresses and a twitter account, using &lt;strong&gt;python&lt;/strong&gt; and &lt;strong&gt;golang&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Let me know what you think about this article and possibly any amendments that can be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>go</category>
      <category>rabbitmq</category>
      <category>python</category>
    </item>
    <item>
      <title>Sending E-mails with Go.</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Sun, 21 Aug 2022 22:05:57 +0000</pubDate>
      <link>https://dev.to/salemzii/sending-e-mails-with-go-ff0</link>
      <guid>https://dev.to/salemzii/sending-e-mails-with-go-ff0</guid>
      <description>&lt;p&gt;Sending email notifications are essential for effective communication between users and service providers. Beneath this notable piece of technology lies several layers of abstractions which might require more than a blog post to have a clear or complete idea of; which in retrospect isn't the aim of this post. &lt;br&gt;
In this short article i will quickly try to uncover some issues i faced whilst trying to implement the email notifications for a service i was building at work.&lt;br&gt;
By default using the standard &lt;a href="https://www.techtarget.com/whatis/definition/SMTP-Simple-Mail-Transfer-Protocol"&gt;SMTP&lt;/a&gt; package provided by golang i.e &lt;code&gt;net/smtp&lt;/code&gt; suffices for most use cases, but depending on the &lt;a href="https://www.activecampaign.com/glossary/email-service-provider"&gt;Email service provider&lt;/a&gt; you're using, you might experience some bottle necks using the &lt;code&gt;smtp&lt;/code&gt; package. &lt;br&gt;
We use &lt;strong&gt;Webmail&lt;/strong&gt; where i work and the first time i tried using &lt;code&gt;net/smtp&lt;/code&gt; with it, i experienced some irregularities, for instance my client was successfully able to authenticate my credentials, and send the mail message using the &lt;code&gt;smtp.SendMail&lt;/code&gt; method, with the sample 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;package mails
import (
         "log"
         "net/smtp"
)

var (
    From_mail     = os.Getenv("FROM_MAIL")
    Mail_password = os.Getenv("MAIL_PASSWORD")
    SMTP_Host     = os.Getenv("HOST")
)
func SendMail(msg string, recipient []string) {
    // Message.
    message := []byte("This is a test email message.")

    // Authentication.
    auth := smtp.PlainAuth("", From_mail, Mail_password, SMTP_Host)

    fmt.Println(auth)
    // Sending email.
    if err := smtp.SendMail(fmt.Sprintf("%s:%d", SMTP_Host, 587), auth, From_mail, recipient, message); err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    log.Println("Email Sent Successfully!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but on the recieving end no mails were delivered.&lt;/p&gt;

&lt;p&gt;After series of relentless searching for a reasonable explanations to why i was experiencing such, i got to learn some email service providers like the one i used preferred sending mails over port &lt;code&gt;465&lt;/code&gt; requiring an ssl connection from the very beginning (without starttls), as compared to the standard &lt;code&gt;587&lt;/code&gt; which uses plain &lt;strong&gt;TCP&lt;/strong&gt; to send the mail traffic to the server with subsequent calls using &lt;strong&gt;Starttls&lt;/strong&gt;. &lt;br&gt;
There's been argument over these ports for a long time, but generally sending mails over &lt;code&gt;port 587&lt;/code&gt; is more recommended as it is provides a much secured transmission layer compared to port &lt;code&gt;465&lt;/code&gt;. How these protocols are implemented depends mainly on the service providers you're using and the network protocol they choose for each port, for example Gmail uses SSL for the SMTP server on port 465 and TLS for port 587, how &lt;strong&gt;SSL&lt;/strong&gt; and &lt;strong&gt;TLS&lt;/strong&gt; are implemented and used for secure data tranmission on the internet is beyond the scope of this article, but you can read more about these protocols &lt;a href="https://www.hostinger.com/tutorials/what-is-ssl-tls-https"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily i found this github &lt;a href="https://gist.github.com/chrisgillis/10888032"&gt;"gist"&lt;/a&gt;, which solved the problem we've been trying to figure out. I refactored the code to fit my use case, but you can get the actual solution from the "gist" link above, now unto the actual code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "net/mail"
    "net/smtp"
    "os"
    "sync"
)

var (
    From_mail     = os.Getenv("FROM_MAIL")
    Mail_password = os.Getenv("MAIL_PASSWORD")
    SMTP_Host     = os.Getenv("HOST")
    Mail_subject  string
    Mail_body     string

    from      *mail.Address
    auth      smtp.Auth
    tlsconfig *tls.Config
    mailwg    sync.WaitGroup
)

type Container struct {
    m       sync.Mutex
    Headers map[string]string
}

func NewContainer() *Container {
    return &amp;amp;Container{
        Headers: make(map[string]string),
    }
}

func main() {

    SendMails("subject", "article message", []string{"testuser1@gmail.com", "testuser2@gmail.com"})
}

func init() {
    from = &amp;amp;mail.Address{Name: "Test-mail", Address: From_mail}
    auth = smtp.PlainAuth("", From_mail, Mail_password, SMTP_Host)
    tlsconfig = &amp;amp;tls.Config{
        InsecureSkipVerify: true,
        ServerName:         SMTP_Host,
    }
}

func SendSSLMail(subject, msg string, recipient string) {
    to := mail.Address{Name: "", Address: recipient}

    Mail_subject = subject
    Mail_body = msg

    // initialize new container object
    container := NewContainer()
    // call mutex.lock to avoid multiple writes to
    // one header instance from running goroutines
    container.m.Lock()
    container.Headers["From"] = from.String()
    container.Headers["To"] = to.String()
    container.Headers["Subject"] = Mail_subject
    // unlock mutex after function returns
    defer container.m.Unlock()

    // Setup message
    message := ""
    for k, v := range container.Headers {
        message += fmt.Sprintf("%s: %s\r\n", k, v)
    }
    message += "\r\n" + Mail_body

    conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", SMTP_Host, 465), tlsconfig)
    if err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    c, err := smtp.NewClient(conn, SMTP_Host)
    if err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    // Auth
    if err = c.Auth(auth); err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    // To &amp;amp;&amp;amp; From
    if err = c.Mail(from.Address); err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    if err = c.Rcpt(to.Address); err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    // Data
    w, err := c.Data()
    if err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    _, err = w.Write([]byte(message))
    if err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    err = w.Close()
    if err != nil {
        log.Printf("Error sending mail %v", err)
        return
    }

    if err = c.Quit(); err != nil {
        return
    }
}

// Concurrently sending mails to multiple recipients
func SendMails(subject, msg string, recipients []string) {
    mailwg.Add(len(recipients))
    for _, v := range recipients {
        go func(recipient string) {
            defer mailwg.Done()
            SendSSLMail(subject, msg, recipient)
        }(v)
    }
    mailwg.Wait()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we declared variables to hold our smtp credentials, then we declared a struct named &lt;code&gt;Container&lt;/code&gt; which basically contains a mutex &lt;code&gt;m&lt;/code&gt; field, that essentially allows us to avoid &lt;a href="https://medium.com/trendyol-tech/race-conditions-in-golang-511314c0b85"&gt;&lt;code&gt;Race Conditions&lt;/code&gt;&lt;/a&gt; i.e when different threads/goroutines try to access and mutate the state of a resource at the same time, this is to lock the &lt;code&gt;Headers&lt;/code&gt; field which is the actual email header containing meta-data of each email to be sent. &lt;br&gt;
The &lt;code&gt;init()&lt;/code&gt; function allows us to initialize some of the resource to be used before the function is called, you can see we initialize the &lt;code&gt;auth&lt;/code&gt; variable with our mail credentials, which returns an &lt;code&gt;smtp.Auth&lt;/code&gt; type; we then move further to set up &lt;code&gt;tlsconfig&lt;/code&gt; which basically determines how the client and server should handle data transfer.&lt;br&gt;
The &lt;code&gt;SendMails&lt;/code&gt; function lets us send mails concurrently to avoid calling the &lt;code&gt;SendSSLMail&lt;/code&gt; function for each number of recipients we want to distribute the mail to, I believe the &lt;code&gt;SendSSLMail&lt;/code&gt; function body is quite straight-forward and doesn't require much explanation, as at the time of publishing this article, this service is being used so i'm pretty sure it is stable enough to be used by anyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Sending mails are very essential to the growth of any business, as they allow direct communication with the customers. Knowing how to effectively build stable email services is quitessential to every software developer out there. I hope this article helps solve any challenge you might encounter while writing mail services with Go.&lt;/p&gt;

&lt;p&gt;Let me know what you think about this article and possibly any amendments that could be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>smtp</category>
      <category>go</category>
      <category>api</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Working with Shell Alias and Functions in linux</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Sat, 26 Mar 2022 10:41:00 +0000</pubDate>
      <link>https://dev.to/salemzii/working-with-shell-alias-and-functions-in-linux-54pe</link>
      <guid>https://dev.to/salemzii/working-with-shell-alias-and-functions-in-linux-54pe</guid>
      <description>&lt;p&gt;Alias helps to pass commands to the linux terminal to run a specific instruction.&lt;br&gt;
The linux terminal is very resourceful, and as such utilizing &lt;strong&gt;Alias&lt;/strong&gt; could be a major boost to your productivity as a developer.&lt;br&gt;
As a "lazy" dev like myself :)) i use aliases for any command that spans beyond 3 words, don't blame me, cos why should i bother typing a long array of words when i could pass in two letters that represents the same command set.&lt;br&gt;
Now you might not be a fan of shortening commands when writing codes, but i find alias quite helpful when you're trying to remember long commands, as they allow you map short, self-made commands rather than the default that comes with the compiler/interpreter or whatever interface you're working on.&lt;br&gt;
For example this is an alias i use whenever i'm trying to run a unittest in my python projects:&lt;br&gt;
&lt;code&gt;alias test="python -m unittest"&lt;/code&gt;&lt;br&gt;
you can see it is much more shorter and saves me the stress of typing everything out repeatedly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Alias
&lt;/h2&gt;

&lt;p&gt;Creating an alias is pretty straight-forward, normally user-defined alias can be created in either the &lt;strong&gt;.bashrc&lt;/strong&gt; or &lt;strong&gt;.bash_aliases&lt;/strong&gt; files, i'd personally recommend using the &lt;em&gt;.bashrc&lt;/em&gt; file for easy organization and referencing.&lt;br&gt;
The syntax for adding an alias is:&lt;br&gt;
&lt;code&gt;sudo nano ~/.bashrc&lt;/code&gt;&lt;br&gt;
&lt;code&gt;alias name=command&lt;/code&gt;&lt;br&gt;
to create an alias you have to indicate with the alias command.&lt;/p&gt;
&lt;h2&gt;
  
  
  Flags when working with alias
&lt;/h2&gt;

&lt;p&gt;Flags are optional arguments passed along side a command to perform specific purposes, they're not unique to only alias as they are used with almost every cli tool.&lt;br&gt;
For instance,you can print out a list of file within a directory using the &lt;code&gt;ls&lt;/code&gt; command, additionally you can use&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls -a&lt;/code&gt; &lt;br&gt;
&lt;code&gt;ls -la&lt;/code&gt;&lt;br&gt;
to get similar but specific outputs.&lt;br&gt;
Flags are usually accompanied with a &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;--&lt;/code&gt; symbol, to indicate they are optional.&lt;br&gt;
There are two common flags when working with alias in linux, one is the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;-p flag&lt;/strong&gt;: that prints out all user-defined alias in a reuseable format.
A common use case is running 
&lt;code&gt;alias -p&lt;/code&gt;
which yields
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias pip='pip3'
alias pip2='pip'
alias push='git push -u origin master'
alias py='python3'
alias python2='python'
alias run='go run'
alias runapp='python manage.py runserver'
alias test='python -m unittest'
alias weather='curl wttr.in'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;on my pc obviously :)&lt;br&gt;
Another common flag is the;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--help flag&lt;/strong&gt;: that returns a help page, instructing how to navigate using alias.
Running 
&lt;code&gt;alias --help&lt;/code&gt;
yields
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ alias --help
alias: alias [-p] [name[=value] ... ]
    Define or display aliases.

    Without arguments, `alias' prints the list of aliases in the reusable
    form `alias NAME=VALUE' on standard output.

    Otherwise, an alias is defined for each NAME whose VALUE is given.
    A trailing space in VALUE causes the next word to be checked for
    alias substitution when the alias is expanded.

    Options:
      -p    print all defined aliases in a reusable format

    Exit Status:
    alias returns true unless a NAME is supplied for which no alias has been defined.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Unaliasing
&lt;/h2&gt;

&lt;p&gt;Unaliasing is basically removing a defined alias, so that a command can't be reached via it's alias.&lt;br&gt;
You can unalias a command by running:&lt;br&gt;
&lt;code&gt;unalias commandName&lt;/code&gt;&lt;br&gt;
for instance i can unalias &lt;strong&gt;push&lt;/strong&gt; in the above alias list by running:&lt;br&gt;
&lt;code&gt;unalias push&lt;/code&gt;&lt;br&gt;
when i run push on the terminal again, i get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ push
bash: push: command not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;obviously this isn't permanent as once the &lt;em&gt;*&lt;em&gt;.bashrc *&lt;/em&gt;_file is reloaded into the terminal memory again, all previously removed commands via **_unalias&lt;/em&gt;** are available again.&lt;br&gt;
To permanently delete an alias, you would have to edit the &lt;em&gt;&lt;strong&gt;.bashrc&lt;/strong&gt;&lt;/em&gt; file and erase that specific command.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Parameters to Alias with Shell Functions
&lt;/h2&gt;

&lt;p&gt;I know! that dosen't sound right, alias do not accept parameters aside their regular pre-defined flags.&lt;br&gt;
So how do we go about a case where we'd like to pass arguments to our alias?&lt;br&gt;
For instance i usually prefer using an alias&lt;br&gt;
&lt;code&gt;build NameOfExedir/NameOfExe&lt;/code&gt; to build golang executables rather than typing &lt;code&gt;go build -o NameOfExedir/NameOfExe -v .&lt;/code&gt;&lt;br&gt;
so i'd rather do &lt;br&gt;
&lt;code&gt;build bin/myproject&lt;/code&gt; instead of &lt;code&gt;go build -o bin/myproject -v .&lt;/code&gt;&lt;br&gt;
In situations like this we apply the use of functions, although functions might be out of context for our current topic of discussion, i find them very useful when working with aliases.&lt;/p&gt;

&lt;p&gt;Functions are commands in linux which are used to create functions or methods. Just like in many programming languages, functions are re-usable chunks of codes that carry out an instruction set.&lt;br&gt;
There are two ways we can declare functions in &lt;em&gt;&lt;strong&gt;.bashrc&lt;/strong&gt;&lt;/em&gt; files, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Using a &lt;strong&gt;Function&lt;/strong&gt; keyword: functions can be defined using the &lt;strong&gt;function&lt;/strong&gt; keyword before specifying the function's name.&lt;br&gt;
&lt;strong&gt;Syntax&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;function build {  }&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using parenthesis: functions can also be defined using the function's name with parenthesis next to it.&lt;br&gt;
&lt;strong&gt;Syntax&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;build() {  }&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run &lt;code&gt;help function&lt;/code&gt; for more information on working with shell functions.&lt;/p&gt;

&lt;p&gt;Back to the above &lt;code&gt;gobuild&lt;/code&gt; question;&lt;br&gt;
we could create an alias that runs the go build functionality and then uses a function to parse the additional parameter, i.e the location the executable would reside. So: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias gobuild="go build -o "&lt;/code&gt;&lt;br&gt;
and then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build(){
        gobuild "$1" -v .
        echo "Finished building project executable"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so when i run, &lt;code&gt;build bin/myproject&lt;/code&gt;&lt;br&gt;
i get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ build bin/myproject
Finished building project executable

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

&lt;/div&gt;



&lt;p&gt;and then when i run &lt;code&gt;ls | grep 'bin'&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;$ ls | grep 'bin'
bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can see there's a binary folder containing my project's executable, all done using a shell function that calls an alias to run a &lt;code&gt;go build&lt;/code&gt; command within a directory of my choosing. This is resourceful as i can now use this build function in whichever project i'd like to workon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this short article we've seen how to optimize our development process by using aliases and functions to shorten long terminal commands.&lt;br&gt;
I hope you enjoyed the article and in the meantime, let me know what you think about the article and possibly any amendments that could be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>cli</category>
      <category>shell</category>
      <category>python</category>
    </item>
    <item>
      <title>Replacing django's default Statreloader with Facebook's Watchman</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Fri, 25 Mar 2022 14:23:19 +0000</pubDate>
      <link>https://dev.to/salemzii/replacing-djangos-default-statreloader-with-facebooks-watchman-d8c</link>
      <guid>https://dev.to/salemzii/replacing-djangos-default-statreloader-with-facebooks-watchman-d8c</guid>
      <description>&lt;p&gt;Ever thought what went on behind the scene when you run &lt;br&gt;
&lt;code&gt;python manage.py runserver&lt;/code&gt; &lt;br&gt;
in your project's base directory during development?&lt;br&gt;
Normally you get a familiar output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 24, 2022 - 11:54:06
Django version 3.2.11, using settings 'wallet.settings'
Starting development server at http://127.0.0.1:8000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As indicated at the top of the terminal output, you see &lt;br&gt;
&lt;code&gt;Watching for file changes with StatReloader&lt;/code&gt; &lt;br&gt;
Statreloader which is the default "file-watcher/file-reloader" for auto-reloading the web server whenever there's a change in .py files during development is no more than a simple &lt;a href="https://github.com/django/django/blob/main/django/utils/autoreload.py"&gt;class&lt;/a&gt; which works by running a loop that checks for file changes every 1 second, this can be quite in-efficient when working on larger projects. &lt;br&gt;
Now except you're experimenting other alternatives to the default Statreloader or working on a quite large codebase where efficiency and resource optimization(like battery usage, memory) is a big deal, i'd advice you to stick with statreloader as it doesn't require any pre-setup to work with. &lt;/p&gt;
&lt;h2&gt;
  
  
  Introducing Watchman
&lt;/h2&gt;

&lt;p&gt;Watchman is a file watching service introduced by Facebook for watching file changes, it relies on the operating system to send signals whenever a change is made to a file.&lt;br&gt;
Django get notified when there's been a recent change to a file and quickly reload's the server to include the recently made changes. &lt;br&gt;
This makes watchman a better alternative as it doesn't keep any process running when there isn't a file change, which leads to better CPU resource optimization.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Watchman
&lt;/h2&gt;

&lt;p&gt;Watchman relies on the operating system it's running on to get file change notification signals, so it's most likely user experience would defer based on your choice of OS.&lt;/p&gt;

&lt;p&gt;Personally i use a linux/debian distro and i found this amazing article on setting up Watchman on your linux pc:&lt;br&gt;
&lt;a href="https://medium.com/@mayankarora/install-watchman-by-facebook-on-ubuntu-19-04-b10de51be7c8"&gt;&lt;strong&gt;Setting up watchman on linux&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
If you're running a windows/Mac Os, you can setup Watchman via the instructions specified on their official docs page: &lt;a href="https://facebook.github.io/watchman/docs/install.html"&gt;Setup Watchman on windows or Macos&lt;/a&gt;&lt;br&gt;
it's pretty straightforward setting it up with chocolatey on windows.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Django to use WatchmanReloader
&lt;/h2&gt;

&lt;p&gt;Getting django to work with watchman is very simple, first you have to cd into your base directory and install watchman client/wrapper for python i.e pywatchman.&lt;/p&gt;

&lt;p&gt;activate your virtual environment&lt;br&gt;
&lt;code&gt;$ source walletenv/bin/activate&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
install pywatchman&lt;br&gt;
&lt;code&gt;$ pip install pywatchman&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;rerun your development server&lt;br&gt;
&lt;code&gt;$ python3 manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;you should see that django is now using WatchmanReloader&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Watching for file changes with WatchmanReloader
Performing system checks...

System check identified no issues (0 silenced).
March 25, 2022 - 13:53:33
Django version 3.2.11, using settings 'wallet.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're building an application that has setups that aren't particularly related to what you're currently working on, you can configure watchman to ignore notifications from these particular dirs/files by simply including a .watchmanconfig file in the same directory where your manage.py file is. &lt;br&gt;
&lt;code&gt;touch .watchmanconfig&lt;/code&gt;&lt;br&gt;
&lt;code&gt;nano .watchmanconfig&lt;/code&gt;&lt;br&gt;
&lt;code&gt;{&lt;br&gt;
  "ignore_dirs": ["DIRECTORY_YOU'd_WANT_TO_IGNORE_CHANGES_FROM"]&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Performance is a vital yardstick when building application that would scale, optimizing development process is also  a very significant factor to this. &lt;br&gt;
In this short article we've seen how to optimize our development process by using a more faster and memory friendly file watching service. &lt;br&gt;
I hope you enjoyed the article and in the meantime, let me know what you think about the article and possibly any amendments that could be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>performance</category>
    </item>
    <item>
      <title>Crafting Middlewares In Go</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Thu, 03 Mar 2022 19:07:58 +0000</pubDate>
      <link>https://dev.to/salemzii/crafting-middlewares-in-go-1elb</link>
      <guid>https://dev.to/salemzii/crafting-middlewares-in-go-1elb</guid>
      <description>&lt;p&gt;When you make a request (as a client) to a server, series of processing are carried out on the said request, before you receive a responses. Some of these processing are done by the base application you are requesting the resources from, but it is most likely that during the request-response cycle several other applications might have interacted and made changes to your requests/response before you get a final result. These third-party applications are generally known as &lt;strong&gt;middlewares&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're a python/javascript developer you'd already be familiar with the term &lt;strong&gt;Middlewares&lt;/strong&gt; as you probably get to interact with them when building apis or so.&lt;br&gt;
Middlewares are basically decorated functions that wraps request handlers  and provide additonal functionalities during the requests/response life cycle.&lt;br&gt;
In django middlewares are added in a particular order into a list, which allows django to process them in a Top-Buttom approach when processing a requests, &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cw-AlwmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a15ybj0c4l51pbanbn2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cw-AlwmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a15ybj0c4l51pbanbn2p.png" alt="How django handles middlewares during the requests/response life cycle" width="602" height="418"&gt;&lt;/a&gt;&lt;br&gt;
and a Buttom-Top approach when returning a response.&lt;br&gt;
In go on the other-hand, you can add a middleware by simply creating a function that recieves a handler as argument and returns it back to the http.handler method as an argument; what do i mean? let's experiment with a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    mux := http.NewServeMux()
    indexHandler := http.HandlerFunc(index)
    server := &amp;amp;http.Server{
        Addr:    ":8000",
        Handler: mux,
    }
    mux.Handle("/index", IndexLogger(indexHandler))

    log.Printf("Serving http on %s", server.Addr)
    log.Fatal(server.ListenAndServe())
}

func IndexLogger(next http.Handler) http.Handler {

    return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        startTime := time.Now()
        log.Printf("%s at %s", r.Method, r.URL.Path)
        next.ServeHTTP(rw, r)
        log.Printf("Finished %s in %v", r.URL.Path, time.Since(startTime))
    })
}

func index(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "hello welcome to the index page")
}

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

&lt;/div&gt;



&lt;p&gt;In this simple example we've created a basic RequestLogger middleware that logs whenever we request for the index Uri.&lt;br&gt;
when we run &lt;br&gt;
&lt;code&gt;go run main.go&lt;/code&gt;&lt;br&gt;
and navigate to &lt;strong&gt;localhost:8000\index&lt;/strong&gt;, you should see a similar output to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go
2022/03/03 13:28:00 Serving http on :8000
2022/03/03 13:28:07 GET at /welcome
2022/03/03 13:28:07 Finished /welcome in 34.394µs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;ServeHTTP&lt;/em&gt;&lt;/strong&gt; calls the Handler's function within the current middleware's method body.&lt;br&gt;
Exciting right? the functionalities we could include to our api-services with this is limitless, say we want to include this logger service to every registered route on our application, we would simply just wrap our  desired function's handler with our &lt;strong&gt;indexLogger&lt;/strong&gt; function, e.g:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func welcome(rw http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(rw, "Welcome to the welcome page")
}

// edit main function to include the welcome handler

WelcomeHandler := http.HandlerFunc(welcome)
mux.Handle("/welcome", IndexLogger(WelcomeHandler))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when we re-run our local server and navigate to &lt;em&gt;/welcome&lt;/em&gt; we'd get a logged response on our terminal, indicating that the IndexLogger functionality was also added to the welcome &lt;strong&gt;URL&lt;/strong&gt; Path, this is cool because not only does it allows similar behaviours within specific uri paths, but because it also supports the &lt;strong&gt;DRY&lt;/strong&gt;(Don't Repeat Yourself) principle of Programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaining multiple http middlewares
&lt;/h2&gt;

&lt;p&gt;Since in go a http middleware recieves a httpHandler and also returns a httpHandler, we can easily chain multiple middlewares that call each other before calling the base application/function.&lt;/p&gt;

&lt;p&gt;For example, let's write another middleware function to check the Requests method of a URI path and return a &lt;strong&gt;method allowed&lt;/strong&gt; &lt;br&gt;
if request method is GET or &lt;strong&gt;not allowed&lt;/strong&gt; if otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func CheckRequestMethod(next http.Handler) http.Handler {

return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        if r.Method != "GET" {
            log.Printf("Only GET requests are accepted on the path!")
            next.ServeHTTP(rw, r)
        fmt.Fprintf(rw, "Method not allowed!")
        } else {
        log.Printf("Method allowed")
        next.ServeHTTP(rw, r)
        fmt.Fprintf(rw, "Your request is valid!")
             log.Printf("Finished checking......")
        }
    })
}


// edit main function to wrap CheckRequestMethod on one of our registered routes.

mux.Handle("/welcome", CheckRequestMethod(IndexLogger(WelcomeHandler)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when we re-run our local server and navigate to /welcome path, we'd notice that both CheckRequestMethod and IndexLogger have taken turns to act on our welcomeHandler before returning a response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go
2022/03/03 19:57:29 Serving http on :8000
2022/03/03 19:57:41 Method allowed
2022/03/03 19:57:41 GET at /welcome
2022/03/03 19:57:41 Finished /welcome in 30.615µs
2022/03/03 19:57:41 Finished checking......
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Flow of Chained Http Middlewares
&lt;/h2&gt;

&lt;p&gt;Consider 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;func ProgramFlow() {

    fmt.Println("First function body")
    func() {
        fmt.Println("Second function body")
        func() {
            fmt.Println("Third Function body")
            time.Sleep(3 * time.Second)
            fmt.Println("Finished third function body")
        }()
        fmt.Println("Finished second function body")
    }()
    fmt.Println("Finished first function body!")

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

&lt;/div&gt;



&lt;p&gt;When we call ProgramFlow() in our main Function, we get an output similar to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ run main.go
First function body
Second function body
Third Function body
Finished third function body
Finished second function body
Finished first function body!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because in go each function is placed in it's own goroutine and it's output is first stored in a WaitGroup till all it's corresponding functions have returned before the it finally returns an output, similarly nested middlewares are treated in the same manner. When you navigate to \welcome;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The webserver passes the control flow to CheckRequestMethod  which logs a response depending on the requests method before executing the next handler.&lt;/li&gt;
&lt;li&gt;The next handler which is also a middleware logs the requests detail before executing the next handler.&lt;/li&gt;
&lt;li&gt;The main application is run and returns the normal response&lt;/li&gt;
&lt;li&gt;The IndexLogger logs it's final response&lt;/li&gt;
&lt;li&gt;The CheckRequestMethod logs it's final response &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Third-Party MiddleWares in go
&lt;/h2&gt;

&lt;p&gt;So far so good, we've been able to understand how middlewares work in go and also how you can write middlewares in your applications where need be. There are tons of libraries that implement several middleware components out-of-the-box for you, when building applications. So many have been created and are actively maintained to fit the best use cases, explore &lt;a href="http://www.gorillatoolkit.org/"&gt;http://www.gorillatoolkit.org/&lt;/a&gt; to see some already built handlers you could use for your next big projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaining Middlewares with the Alice Package
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/justinas/alice"&gt;Alice&lt;/a&gt; is a go library that can be used to chain mulitple middleware functions and application handler together.&lt;/p&gt;

&lt;p&gt;with Alice we do not need to pass each middleware handler as a parameter to the next, like we did in the above examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mux.Handle("/welcome",CheckRequestMethod(IndexLogger(WelcomeHandler)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead we could do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "github.com/justinas/alice"

// edit our main function to create a variable that stores all our middlewares 

allhandlers := alice.New(CheckRequestMethod, IndexLogger)

// add middlewares to registered route

mux.Handle("/welcome", allhandlers.Then(WelcomeHandler))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and just like we've chained all our middlewares with alice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Middlewares are a great way to write re-usable pieces of code that can add great functionalities to whatever we are building, we only scratched the surface of what we could do with middlewares and in later articles we'd go into details on how to build applicable middlewares for our applications. &lt;br&gt;
Meanwhile i'd suggest you go through more articles/videos on the subject matter to gain deeper understanding on how to go around building middlewares.&lt;/p&gt;

&lt;p&gt;Let me know what you think about this article and possibly any amendments that could be made to improve it's user experience, thanks for reading and have a great time!&lt;/p&gt;

</description>
      <category>go</category>
      <category>design</category>
      <category>backend</category>
      <category>microservices</category>
    </item>
    <item>
      <title>The unicode encoding system</title>
      <dc:creator>salem ododa</dc:creator>
      <pubDate>Fri, 11 Feb 2022 17:53:27 +0000</pubDate>
      <link>https://dev.to/salemzii/the-unicode-encoding-system-48jb</link>
      <guid>https://dev.to/salemzii/the-unicode-encoding-system-48jb</guid>
      <description>&lt;p&gt;Have you ever wondered what went on behind the scene when you type series of texts on your keyboard? or send an e-mail to a friend from Rwanda who speaks french? how is the mail converted from english to french, how does the computer find the equivalent for each character you type? does the computer understand english? so many questions comes to heart. Well what we can all agree for sure is that the computer understands only 2 characters "0" and "1" respectively, these can be referred to as &lt;a href="https://whatis.techtarget.com/definition/bit-binary-digit"&gt;bits&lt;/a&gt;.This implies that an alphabets has to be interpreted as numbers for computers to store texts.&lt;/p&gt;

&lt;p&gt;So how were all these characters in-cooperated  into the computer's system? well in the early days of computer's inception (1960s), the primary means of communication between people were the use of teletypes(typewriters, teleprinters, etc).&lt;br&gt;
These teletypes used a 5-bit encoding system which could range up to 32 character sets(2 ^ 5 = 32), the problem with this system was that it didn't provide enough space to represent all the english letters(a-z, A-Z), punctuation signs, numbers and other quintessential characters needed for effective communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Ascii
&lt;/h2&gt;

&lt;p&gt;Due to the limitations of the 32-bits encoding system, there was need for a much better and standardized means of communication, in october 1960 The American Standards Association (ASA), now the American National Standards Institute (ANSI),led by &lt;a href="https://www.computer.org/profiles/robert-bemer"&gt;Robert William Bemer&lt;/a&gt; (February 8, 1920 – June 22, 2004 began work on &lt;strong&gt;ASCII&lt;/strong&gt; which is an acronym for &lt;strong&gt;American Standard Code for Information Interchange&lt;/strong&gt;.In 1963 &lt;strong&gt;ASA&lt;/strong&gt; introduced the first version of Ascii, unlike the former it was a 7-bit encoding system that could hold up to 128 character sets(2 ^ 7 = 128), numbered 0-127.&lt;/p&gt;

&lt;p&gt;So for the English language, which has 26 letters, ASCII had enough slots for both upper and lower letter cases, numbers (0 to 9), punctuation marks, and unprintable control codes for teleprinters.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I0OTI0-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kw2laiatwajblpg8946f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I0OTI0-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kw2laiatwajblpg8946f.png" alt="The Ascii Table" width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was a great improvement obviously and by march of 1968, then US President Lyndon B. Johnson, announced that henceforth all computer systems should adopt the Ascii system as the default standard for information interchange(see more &lt;a href="https://www.presidency.ucsb.edu/documents/memorandum-approving-the-adoption-the-federal-government-standard-code-for-information#axzz1s2VIkMsP"&gt;here&lt;/a&gt;), but as with every technology Ascii had it's own bottlenecks, one of which was it's in-ability to represent non-english characters, So, for European languages that use accented alphabets like German ä, ë, or Polish ź, ł, ę, ASCII wasn’t a favorable option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicode to the rescue
&lt;/h2&gt;

&lt;p&gt;Once again there was need for a much more diverse encoding system, that breached the disparities in communication and enhanced universal inclusion, as all other attempt towards tackling the problem resulted in a more complicated problem, during this period, globalization and internalization had become a core aspect of marketing and distribution, therefore global inclusion was vital at this point.&lt;/p&gt;

&lt;p&gt;So in 1988 Joe Becker a computer scientist and expert on multilingual computing introduced an encoding scheme known as &lt;strong&gt;Unicode&lt;/strong&gt;(Uniform character enCoding) in which each character is assigned a unique number known as a &lt;strong&gt;Code Point&lt;/strong&gt;(A code point is the value that a character is given in the Unicode standard). This was a real breakthrough as not only was this applicable to english language alone, but also for every language around the world. The objective of Unicode was/is to unify all the different encoding schemes so that the confusion between computers can be limited to the very minimum.&lt;br&gt;
Currently the Unicode is of three variants namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UTF-8&lt;/strong&gt;: which is made of one byte(or 8 bits) and is well known for it's wide adoption in email systems and the internet in general&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UTF-16&lt;/strong&gt;: as you guessed is made up of two bytes(or 16 bits)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UTF-32&lt;/strong&gt;: this encoding scheme utilizes four bytes(or 32 bits) to represent textual characters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: UTF means Unicode Transformation Unit.&lt;/p&gt;

&lt;p&gt;And that brings us to the end of this article, of course there's much more to encoding as this is just a quick see-through of the broad field of encoding/multi-lingual processing.&lt;br&gt;
If you enjoyed this article, kindly leave a comment on what you learned from this one. Peace Out :)&lt;/p&gt;

</description>
      <category>encoding</category>
      <category>python</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
