<?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: Piyush Goyani</title>
    <description>The latest articles on DEV Community by Piyush Goyani (@piyushmultiplexer).</description>
    <link>https://dev.to/piyushmultiplexer</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%2F133027%2F67f262a3-0663-48ea-b1a9-078e5ca830e3.png</url>
      <title>DEV Community: Piyush Goyani</title>
      <link>https://dev.to/piyushmultiplexer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/piyushmultiplexer"/>
    <language>en</language>
    <item>
      <title>Build CLI App in Python with Click and Publish to PyPI</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Fri, 24 Feb 2023 10:45:39 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/build-cli-app-in-python-with-click-and-publish-to-pypi-1d5h</link>
      <guid>https://dev.to/piyushmultiplexer/build-cli-app-in-python-with-click-and-publish-to-pypi-1d5h</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Of course, you all are aware of CLI(Command Line Interface) tools, because you might use any OS like Linux-based, Mac or Windows, you have used these tools in your life. These are Git CLI, language interpreters and runtimes(Python, Node, Ruby, Java, Go etc), system commands and network utilities(reboot, restart, ping etc), editors like nano, vim and there many other tools and command line software that we use nowadays which are minimalist to fulfil our needs and save time. In this tutorial, I'll explain how to implement a CLI app that gives answers to your input about me based on CLI inputs. Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't want to set up and go with development/install/publish flow and directly want to try CLI, then you can clone or direct install the package.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/piyush-multiplexer/click-piyush"&gt;GitHub Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, we'll be using Python 3 for this project. let's install basic dependencies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install PIP, python package manager, used to install Python packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install a virtual environment for this project, which isolates python packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the project directory( &lt;strong&gt;click-piyush&lt;/strong&gt; ), set up &lt;em&gt;virtualenv&lt;/em&gt; and activate. Then install &lt;a href="https://github.com/pallets/click"&gt;&lt;em&gt;click&lt;/em&gt;&lt;/a&gt; with pip, the library to make CLI apps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's Code
&lt;/h2&gt;

&lt;p&gt;Let's create a python file named &lt;em&gt;clickpiyush.py&lt;/em&gt; where we'll write the below code.&lt;br&gt;
&lt;/p&gt;

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

@click.command()
def age():
    """Get Age"""
    click.echo("I'm 2X years older, shouldn't be matter.")

if __name__ == ' __main__':
    age()

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

&lt;/div&gt;



&lt;p&gt;Here we are importing the package &lt;strong&gt;click&lt;/strong&gt; that is used to make the CLI app.&lt;br&gt;&lt;br&gt;
Then we are adding one command to get the age and method for that command, which prints the age. Then call the method when the script is executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python test.py 
I'm 2X years older, shouldn't be matter.

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

&lt;/div&gt;



&lt;p&gt;Here, as you can see, you are not seeing any feeling like the CLI app but a simple script is running and printing some stuff, just like a normal python program does.&lt;br&gt;&lt;br&gt;
Now you can register for options and arguments(next section) or make command groups for adding multiple commands or nesting of commands. Let's do that.&lt;br&gt;
&lt;/p&gt;

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

@click.group()
def cli():
    pass

@click.command()
def age():
    """Get Age"""
    click.echo("I'm 2X years older, shouldn't be matter.")

cli.add_command(age)

if __name__ == ' __main__':
    cli()

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

&lt;/div&gt;



&lt;p&gt;In this, we have made slight changes. We are adding multi-command using group functionality of click. inside that, we added one method which passes invocation as it's empty. Using that &lt;em&gt;cli()&lt;/em&gt; method, we are registering the command using &lt;em&gt;add_command&lt;/em&gt; and passing an argument of the commanding method(&lt;em&gt;age&lt;/em&gt;). Now you can see the output below. As you can see click auto-generate beautiful Usage guide, options and help pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python test.py 
Usage: test.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help Show this message and exit.

Commands:
  age Get Age

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

&lt;/div&gt;



&lt;p&gt;Now we'll add different types of commands and functionality to our CLI app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@click.command()
@click.option('--name', prompt='Identify youself by name')
def greet(name):
    """Describe this tool with colors to You."""
    click.secho(f"Hello {name}", bold=True, bg='green', fg='black')
    click.secho(
        "This is Command Line Interface which gives information of maker named Piyush.", bg='blue', fg='white')

cli.add_command(greet)

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6hRnBwHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1677230055299/27a08242-81e1-4adc-8509-9bef069f8fcd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6hRnBwHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1677230055299/27a08242-81e1-4adc-8509-9bef069f8fcd.png" alt="" width="631" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this &lt;strong&gt;greet&lt;/strong&gt; command, we are asking for &lt;strong&gt;&lt;em&gt;--name&lt;/em&gt;&lt;/strong&gt; option using the runtime prompt, you can configure it as you want. which is stored in the &lt;strong&gt;name&lt;/strong&gt; variable for further access to the method. Inside that, we are printing two lines with different background colours and font colours in CLI using &lt;a href="https://click.palletsprojects.com/en/8.1.x/api/#click.secho"&gt;&lt;code&gt;click.secho()&lt;/code&gt;&lt;/a&gt;. It combines echo and style functionality of click in one method and styles of the font as bold.&lt;/p&gt;

&lt;p&gt;Let's add another command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@click.command()
@click.option('--desc', default=False, show_default=True, help='Show detailed Info.')
def bio(desc):
    """Basic Bio"""
    if desc:
        click.echo("Hey, this is piyush here, thanks for your interest.\nTo know more about me please run this CLI and different commands.\nThank You!")
    else:
        click.echo("This is me, and describing self.")

cli.add_command(bio)

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tf4Crvlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1677230775190/1a8b67a0-05ea-4d1b-9415-0c0b41f0dccb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tf4Crvlx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1677230775190/1a8b67a0-05ea-4d1b-9415-0c0b41f0dccb.png" alt="" width="566" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;bio&lt;/strong&gt; command, the user can get information about me, but basic if not input is passed. To get detailed info &lt;code&gt;--desc true&lt;/code&gt; flag must be passed. This argument can be configured with the &lt;em&gt;@click.option&lt;/em&gt; method. In which you can describe the default value, enabling the default value in the help doc and help text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Code and Output
&lt;/h3&gt;

&lt;p&gt;Here is the full code of my package script &lt;em&gt;clickpiyush.py&lt;/em&gt; and the output is below for your reference.&lt;br&gt;
&lt;/p&gt;

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

@click.group()
def cli():
    pass

@click.command()
@click.option('--name', prompt='Identify youself by name')
def greet(name):
    """Describe this tool with colors to You."""
    click.secho(f"Hello {name}", bold=True, bg='green', fg='black')
    click.secho(
        "This is Command Line Interface which gives information of maker named Piyush.", bg='blue', fg='white')

@click.command()
@click.option('--desc', default=False, show_default=True, help='Show detailed Info.')
def bio(desc):
    """Basic Bio"""
    if desc:
        click.echo("Hey, this is piyush here, thanks for your interest.\nTo know more about me please run this CLI and different commands.\nThank You!")
    else:
        click.echo("This is me, and describing self.")

@click.command()
def age():
    """Get Age"""
    click.echo("I'm 2X years older, shouldn't be matter.")

@click.command()
def skills():
    """Get my dummy skills set with progress bar"""
    skill_set = ["JavaScript", "Python", "GraphQL", "C", "TypeScript", "VueJS",
                 "NuxtJS", "Socket Programming", "Machine Learning", "NodeJS", "Linux"]

    with click.progressbar(skill_set, label='Getting skills', length=len(skill_set)-1, show_eta=False, color='blue') as skill_list:
        for skill in skill_list:
            click.echo(f" {skill}")
            time.sleep(0.3)

@click.command()
def blog():
    """Get My blog URL"""
    blog_url = "https://blog.thesourcepedia.org/"
    click.echo(f"{blog_url} Wanna visit [y/n]: ", nl=False)
    c = click.getchar()
    click.echo(c)
    if c == 'y':
        click.echo("Launching Piyush's Blog")
        click.launch(blog_url)

@click.command()
def portfolio():
    """Launch my Portfolio!"""
    click.launch("https://piyushgoyani.thesourcepedia.org/")

# @click.command()
# @click.Choice()
cli.add_command(greet)
cli.add_command(bio)
cli.add_command(age)
cli.add_command(skills)
cli.add_command(blog)
cli.add_command(portfolio)

if __name__ == ' __main__':
    cli()

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running CLI Locally
&lt;/h3&gt;

&lt;p&gt;To run the and see output execute &lt;a href="http://clickpiyush.py"&gt;clickpiyush.py&lt;/a&gt; file with no argument or option so it'll show help and all command as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python clickpiyush.py
Usage: clickpiyush.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help Show this message and exit.

Commands:
  age Get Age
  bio Basic Bio
  blog Get My blog URL
  greet Describe this tool with colors to You.
  portfolio Launch my Portfolio!
  skills Get my dummy skills set with progress bar

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

&lt;/div&gt;



&lt;p&gt;In this, we are launching a website in a browser based on the user input, showing a progress bar in skill command and more.&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/piyush-multiplexer/click-piyush"&gt;Source Repository&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prepare for Package
&lt;/h2&gt;

&lt;p&gt;Let's create a &lt;strong&gt;&lt;em&gt;setup.py&lt;/em&gt;&lt;/strong&gt; file and paste the below configuration. This file contains the name of the package, version, inside modules, requirements, entry points and more configurable things.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from setuptools import setup

setup(
    name='clickpiyush',
    version='1.0.1,
    py_modules=['clickpiyush'],
    install_requires=['Click',],
    entry_points={
        'console_scripts': [
            'clickpiyush = clickpiyush:cli'
        ]
    }
)

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Local Package
&lt;/h3&gt;

&lt;p&gt;We have created a setup file, now we can install our CLI app and run it just like a normal program, so don't need to invoke a python interpreter.&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 --editable .


Obtaining file:///home/piyush/Documents/prs/click-piyush
Requirement already satisfied: Click in ./venv/lib/python3.8/site-packages (from clickpiyush==1.0.1) (8.1.3)
Installing collected packages: clickpiyush
  Running setup.py develop for clickpiyush
Successfully installed clickpiyush

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

&lt;/div&gt;



&lt;p&gt;As you can see &lt;strong&gt;&lt;em&gt;clickpiyush&lt;/em&gt;&lt;/strong&gt; package is installed successfully, now you can use it with the name of the CLI app.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Publish to PyPI
&lt;/h2&gt;

&lt;p&gt;Till now whatever we make, run and install was on our system. Now we want to publish our package to PyPI(Python Package Index) so other users can download our CLI app and use it in their system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python setup.py sdist

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

&lt;/div&gt;



&lt;p&gt;Once we run the above command, we have a new directory &lt;em&gt;dist/&lt;/em&gt;, which contains our distribution or simply archived package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running sdist
running egg_info
writing clickpiyush.egg-info/PKG-INFO
writing dependency_links to clickpiyush.egg-info/dependency_links.txt
writing entry points to clickpiyush.egg-info/entry_points.txt
writing requirements to clickpiyush.egg-info/requires.txt
writing top-level names to clickpiyush.egg-info/top_level.txt
reading manifest file 'clickpiyush.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'clickpiyush.egg-info/SOURCES.txt'
running check
creating clickpiyush-1.0.1
creating clickpiyush-1.0.1/clickpiyush.egg-info
copying files to clickpiyush-1.0.1...
copying LICENSE -&amp;gt; clickpiyush-1.0.1
copying README.md -&amp;gt; clickpiyush-1.0.1
copying clickpiyush.py -&amp;gt; clickpiyush-1.0.1
copying setup.cfg -&amp;gt; clickpiyush-1.0.1
copying setup.py -&amp;gt; clickpiyush-1.0.1
copying clickpiyush.egg-info/PKG-INFO -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
copying clickpiyush.egg-info/SOURCES.txt -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
copying clickpiyush.egg-info/dependency_links.txt -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
copying clickpiyush.egg-info/entry_points.txt -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
copying clickpiyush.egg-info/requires.txt -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
copying clickpiyush.egg-info/top_level.txt -&amp;gt; clickpiyush-1.0.1/clickpiyush.egg-info
Writing clickpiyush-1.0.1/setup.cfg
Creating tar archive
removing 'clickpiyush-1.0.1' (and everything under it)

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

&lt;/div&gt;



&lt;p&gt;Now let's install twine. It's a utility to publish python packages to PyPI and then upload generated distribution.&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 twine
twine upload dist/*

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

&lt;/div&gt;



&lt;p&gt;After you run the command, you'll show that distribution is uploading to PyPI and asking for your credentials. Once you enter those, the package will be published successfully and listed in PyPI as this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/clickpiyush/"&gt;https://pypi.org/project/clickpiyush/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now anyone can install this package by using the below command.&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 clickpiyush

$ clickpiyush
Usage: clickpiyush [OPTIONS] COMMAND [ARGS]...

Options:
  --help Show this message and exit.

Commands:
  age Get Age
  bio Basic Bio
  blog Get My blog URL
  greet Describe this tool with colors to You.
  portfolio Launch my Portfolio!
  skills Get my dummy skills set with progress bar

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

&lt;/div&gt;



&lt;p&gt;I hope you enjoyed this article. Share, subscribe and stay tuned for more!&lt;/p&gt;

</description>
      <category>python</category>
      <category>cli</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Displaying Hashnode Posts on Personal Site with RSS</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Fri, 21 Oct 2022 07:30:02 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/displaying-hashnode-posts-on-personal-site-with-rss-454k</link>
      <guid>https://dev.to/piyushmultiplexer/displaying-hashnode-posts-on-personal-site-with-rss-454k</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Hello,&lt;/p&gt;

&lt;p&gt;I hope you are writing articles on Hashnode, either in Personal, community or company blogs. You may want to link and display your written articles in your personal websites or portfolio where others can see only your article with other content. Here we'll see two ways with which you can achieve above task easily.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solutions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Hashnode Official API
&lt;/h4&gt;

&lt;p&gt;Hashnode provides official GraphQL API from which you can retrieve various content and display. You can test their &lt;a href="https://api.hashnode.com/"&gt;playground here.&lt;/a&gt; With this API you can get various type content like featured posts, users posts and publications, manipulate articles and related data. You may require PAT(Personal Access Token) for some of access.&lt;/p&gt;

&lt;p&gt;For more information, refer &lt;a href="https://catalins.tech/hashnode-api-how-to-display-your-blog-articles-on-your-portfolio-page"&gt;this article&lt;/a&gt; by Catalin Pit.&lt;/p&gt;

&lt;h4&gt;
  
  
  RSS Parsing
&lt;/h4&gt;

&lt;p&gt;Another way is RSS Parsing. In this, RSS URL of publication is required to retrieve and process data. Here I'll take &lt;a href="https://blog.thesourcepedia.org/"&gt;my blogs&lt;/a&gt; rss and process it and display articles which are written by me(aka Piyush Goyani).&lt;/p&gt;

&lt;p&gt;First, I have created Backend NodeJS API in which I have installed &lt;a href="https://github.com/rbren/rss-parser"&gt;&lt;code&gt;rss-parser&lt;/code&gt;&lt;/a&gt; package to parse RSS feed of blog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Parser = require('rss-parser');

async getRss() {
  const parser: Parser = new Parser();
  const url = 'https://blog.thesourcepedia.org/rss.xml';
  const feed = await parser.parseURL(url);
  return feed.items.map((item) =&amp;gt; {
    return {
      title: item['title'],
      coverImage: item['cover_image'],
      creator: item['creator'],
      link: item['link'],
      pubDate: item['pubDate'],
    };
  });
}

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

&lt;/div&gt;



&lt;p&gt;Here, as you can see, RSS feed URL is parsed and parser return whole array, which further mapped with specific key/value object and return as API response.&lt;/p&gt;

&lt;p&gt;In the frontend side, which is Vue component where All articles are being rendered by calling API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    {{ items }} // render posts
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
export default {
  data() {
    return {
      items: [],
    };
  },
  mounted() {
    fetch("https://api.thesourcepedia.org/blog/getRss")
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        this.items = data.filter((post) =&amp;gt; post.creator === "Piyush Goyani");
      });
  },
};

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

&lt;/div&gt;



&lt;p&gt;Here I'm calling &lt;code&gt;/getRss&lt;/code&gt; API which returns article array, and here I can filter which specific author(e.g myself) and display only those posts which I have written in &lt;a href="https://piyushgoyani.thesourcepedia.org/"&gt;my personal site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c5xGrnQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666336444978/abDqVi0pe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c5xGrnQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1666336444978/abDqVi0pe.png" alt="PersonalSitePosts.png" width="880" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can filter and process RSS in different way as per you need.&lt;/p&gt;

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

&lt;p&gt;I hope you enjoyed this article and found useful. Give a thumb and subscribe for more interesting stuff.&lt;/p&gt;

</description>
      <category>rss</category>
      <category>hashnode</category>
      <category>node</category>
      <category>blogging</category>
    </item>
    <item>
      <title>Preliminary Go Language for Beginners</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Wed, 19 Oct 2022 07:32:36 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/preliminary-go-language-for-beginners-8k7</link>
      <guid>https://dev.to/piyushmultiplexer/preliminary-go-language-for-beginners-8k7</guid>
      <description>&lt;p&gt;&lt;a href="https://go.dev/"&gt;Go&lt;/a&gt; is the programming language that was Invented and backed by Google and is now used by many companies and programmers worldwide.&lt;/p&gt;

&lt;p&gt;There aren't any use-case limitations with Go to build something as you can build anything with it, But it's mostly used for CLI Tooling, Network Services and APIs, Web applications and DevOps.&lt;/p&gt;

&lt;p&gt;The Go Language is known for the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Built-in Concurrency Support&lt;/li&gt;
&lt;li&gt;Safety&lt;/li&gt;
&lt;li&gt;Garbage Collection&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Portability / Cross Platform &lt;/li&gt;
&lt;li&gt;Binary Generation&lt;/li&gt;
&lt;li&gt;Standard Library and Package Management&lt;/li&gt;
&lt;li&gt;Built-in Testing Support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The language is not intended for replacement of any other languages like C, C++, Python, Rust or any other as these languages have their own beauty and places in the market and people who adopted them for a long time.&lt;/p&gt;

&lt;p&gt;Let's dive into installation and Basic Go Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Download Go
&lt;/h4&gt;

&lt;p&gt;Download the Go archive from &lt;a href="https://go.dev/dl/"&gt;official site&lt;/a&gt; as per your choice. Here, I'm using Linux so the rest steps are accordingly.&lt;/p&gt;

&lt;p&gt;Go to the downloaded directory and run this command from the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rm -rf /usr/local/go &amp;amp;&amp;amp; sudo tar -C /usr/local -xzf go1.19.2.linux-amd64.tar.gz

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

&lt;/div&gt;



&lt;p&gt;This will remove the old installation of Go and extract the downloaded version to the &lt;code&gt;/usr/local&lt;/code&gt; directory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add PATH
&lt;/h4&gt;

&lt;p&gt;Edit &lt;code&gt;.bashrc&lt;/code&gt; file and &lt;code&gt;sudo nano .bashrc&lt;/code&gt;add PATH and save.&lt;code&gt;export PATH=$PATH:/usr/local/go/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Check the installed version of GO with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go version
// go version go1.19.2 linux/amd64

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;demo&lt;/code&gt; project directory and go inside the directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir demo &amp;amp;&amp;amp; cd demo

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

&lt;/div&gt;



&lt;p&gt;Run the below command to enable Dependency tracking in your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go mod init example/demo

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

&lt;/div&gt;



&lt;p&gt;This will create a file named &lt;code&gt;go.mod&lt;/code&gt; with the below content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module example/demo

go 1.19

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

&lt;/div&gt;



&lt;p&gt;This file is generally used to manage internal and external dependencies, which stay within the project.&lt;/p&gt;

&lt;p&gt;Create &lt;em&gt;init.go&lt;/em&gt; file with your favourite text editor,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano init.go

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

&lt;/div&gt;



&lt;p&gt;and paste the below code and save.&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"

func main() {
    fmt.Println("First program of GoLang!")
}

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explaination
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;package main&lt;/strong&gt; : It declares the &lt;code&gt;main&lt;/code&gt; package, which may contain all sub-functionality within the same directory linked to this file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;import "fmt"&lt;/strong&gt; : Importing &lt;code&gt;fmt&lt;/code&gt;, one of the standard library packages of Go, which contains functionality for console output and text formatting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;func main()&lt;/strong&gt;: Defining &lt;code&gt;main()&lt;/code&gt; function, which by default called first when program get executed, similar like main in C/C++.&lt;/p&gt;

&lt;h4&gt;
  
  
  Running Go Code
&lt;/h4&gt;

&lt;p&gt;To run the Go program execute the below command in the terminal and see Output.&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 .
// First program of GoLang!

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

&lt;/div&gt;



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

&lt;p&gt;I hope you enjoyed this article. Stay tuned and subscribe for more Go Language posts and other useful tutorials.&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
    </item>
    <item>
      <title>AWS Amplify: All in One Framework that you need</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Mon, 19 Sep 2022 15:43:47 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/aws-amplify-all-in-one-framework-that-you-need-1jo8</link>
      <guid>https://dev.to/piyushmultiplexer/aws-amplify-all-in-one-framework-that-you-need-1jo8</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/amplify/"&gt;Amazon Amplify&lt;/a&gt; is a framework for building full-stack applications within no time. It can be integrated with various frameworks and libraries for Mobile, Web and Desktop Application Development including JavaScript, iOS, Ionic, Flutter, React, Vue and many more.&lt;/p&gt;

&lt;p&gt;In this article, We are going to learn How to use AWS Amplify for Developing a Full Stack Text Summarization Application in which we'll include Amplify CLI, Auth, UI Library, API, Serverless Functions, Deployment, and Debugging of Application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Amazon AWS Account &lt;/li&gt;
&lt;li&gt;System from where you can access your AWS account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install vue-cli and create vue project.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @vue/cli
vue create ml-with-amplify
// select vue3 version
cd ml-with-amplify

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This was the front end of our project. Now we'll set up backend API and services for our project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Install the Amplify CLI.
&lt;/h4&gt;

&lt;p&gt;The Amplify CLI is a command line toolchain that runs locally in order to communicate with your app backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @aws-amplify/cli@latest
// OR with npm
curl -sL https://aws-amplify.github.io/amplify-cli/install | bash &amp;amp;&amp;amp; $SHELL

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install &amp;amp; Configure Amplify UI
&lt;/h3&gt;

&lt;p&gt;To install Amplify UI with Vue integration run the below command,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @aws-amplify/ui-vue aws-amplify

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

&lt;/div&gt;



&lt;p&gt;Edit &lt;strong&gt;src/main.js&lt;/strong&gt; file and add below content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createApp } from "vue";
import App from "./App.vue";
import './assets/style.css'
import AmplifyVue from "@aws-amplify/ui-vue";
import router from "./router";

const app = createApp(App);
app.use(router);
app.use(AmplifyVue);
app.mount("#app");

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

&lt;/div&gt;



&lt;p&gt;To set up amplify backend in our project, run the following command from your project's root folder (ml-with-amplify): you can customize the selections. See the output below.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZES8q6AG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662450587698/3dhZnsLHv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZES8q6AG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662450587698/3dhZnsLHv.png" alt="Amplify Init 1.png" width="792" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cL_FUgDa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662450642575/-d2rfCeTU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cL_FUgDa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662450642575/-d2rfCeTU.png" alt="Amplify Init 2.png" width="880" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Auth
&lt;/h2&gt;

&lt;p&gt;To set up &lt;a href="https://docs.amplify.aws/cli/auth/overview/"&gt;Amplify Auth&lt;/a&gt; in our project run the below command and review selections.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Nn2zdX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662455682653/L0GqxCWjZ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Nn2zdX5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662455682653/L0GqxCWjZ.png" alt="Add Amplify Auth.png" width="880" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amplify Auth uses &lt;a href="https://aws.amazon.com/cognito/"&gt;Amazon Cognito&lt;/a&gt; for Auth mechanisms like Sign Up, Sign In and other Access Control. You can customize it as per your need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrate Auth with Amplify UI
&lt;/h3&gt;

&lt;p&gt;Edit &lt;strong&gt;src/App.vue&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;lt;template&amp;gt;
  &amp;lt;authenticator :form-fields="formFields"&amp;gt;
    &amp;lt;template v-slot="{ user, signOut }"&amp;gt;
      &amp;lt;template v-if="user"&amp;gt;
        &amp;lt;AppHeader :user="user" :sign-out="signOut"&amp;gt;&amp;lt;/AppHeader&amp;gt;
        &amp;lt;router-view class="scrollbar" :user="user"&amp;gt;&amp;lt;/router-view&amp;gt;
      &amp;lt;/template&amp;gt;
    &amp;lt;/template&amp;gt;
  &amp;lt;/authenticator&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import "@aws-amplify/ui-vue/styles.css";
import { Amplify, Auth } from "aws-amplify";
import awsconfig from "./aws-exports";
import AppHeader from "./components/app-header.vue";

Amplify.configure(awsconfig);
Auth.configure(awsconfig);

const formFields = {
  signIn: {
    username: {
      labelHidden: true,
      placeholder: "Enter your username",
      isRequired: true,
      label: "",
    },
  },
  signUp: {
    username: {
      labelHidden: true,
      placeholder: "Create username",
      isRequired: true,
      label: "",
    },
    email: {
      labelHidden: true,
      placeholder: "Enter Your Email Here",
      isRequired: true,
      label: "",
    },
  },
  resetPassword: {
    username: {
      labelHidden: true,
      placeholder: "Enter your username",
      isRequired: true,
      label: "",
    },
  },
};
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Here we are Configuring Amplify Auth with &lt;em&gt;awsConfig&lt;/em&gt;(aws-exports.js file) which is auto-generated by Amplify. We use &lt;a href="https://docs.amplify.aws/lib/auth/getting-started/q/platform/js/"&gt;component&lt;/a&gt; which is Amplify Auth component for Vue, which is used for Sign Up, Sign In, Reset Password, Social Login and Customization Auth Options. It can be customizable. Here in &lt;strong&gt;formFields&lt;/strong&gt; object we are customizing Authenticator SignIn, Sign Up, and Reset Password Form's fields. In &lt;strong&gt;app-header.vue&lt;/strong&gt; we have passed &lt;strong&gt;signOut&lt;/strong&gt; method of the authenticator component to split functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push Deployment
&lt;/h2&gt;

&lt;p&gt;Run the below command to deploy our frontend and backend app in the cloud in a single workflow.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uTeZ0XsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456160879/uprhADFl4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uTeZ0XsP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456160879/uprhADFl4.png" alt="Push Amplify.png" width="880" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List all deployed apps in Amplify Console. You can create a new app from here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2bQlJIOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456368436/KuF7dTrdv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2bQlJIOz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456368436/KuF7dTrdv.png" alt="App in Amplify Console.png" width="880" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Review detailed view of our application's backend environment. Here you can see deployment details, Added categories, actions and commands to install this backend in a new project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2s01tOZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456491417/m8HjFcbpH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2s01tOZM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456491417/m8HjFcbpH.png" alt="Backend App Detail.png" width="880" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect Branch
&lt;/h2&gt;

&lt;p&gt;In the Hosting environment section, you can connect any Git Version Control provider and connect the repository branch to link the code. Here we are selecting &lt;em&gt;GitHub&lt;/em&gt; as a provider. Click &lt;strong&gt;Connect Branch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HlKZmHPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456531638/5QUJQSi6P.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HlKZmHPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456531638/5QUJQSi6P.png" alt="Connect Deployment.png" width="880" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Repository
&lt;/h3&gt;

&lt;p&gt;After successful authorization, we need to select the repository where our code is hosted and the name of the branch. Click &lt;strong&gt;Next.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jcRE2KSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456632285/T2ORpBqR8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jcRE2KSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456632285/T2ORpBqR8.png" alt="Deploy - Connect GH Branch.png" width="870" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create role
&lt;/h3&gt;

&lt;p&gt;In this section, we need to create an AWS role to Allow Access to resources on our behalf so it can auto-create instances, and pools, and deploy them. After review click &lt;strong&gt;Create Role.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WVOY8R34--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456772665/PxMinotyK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WVOY8R34--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662456772665/PxMinotyK.png" alt="Deploy - Create Service Role.png" width="880" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Settings
&lt;/h3&gt;

&lt;p&gt;In this section you can configure the build section, it will auto-detect frameworks, here Vue is detected as Frontend Framework and Amplify as Backend. After the necessary configuration click next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QCo493o2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458440231/psfUOWXqO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QCo493o2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458440231/psfUOWXqO.png" alt="Deploy - Build Setting.png" width="849" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Review
&lt;/h3&gt;

&lt;p&gt;Review final details and settings and all ok then click &lt;strong&gt;Save and deploy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VhV22LGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458484288/DN8JO07L7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VhV22LGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458484288/DN8JO07L7.png" alt="Deploy - Review.png" width="695" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After deploying go back to the Hosting section app detail page, where you can see the pipeline is running with four steps which include Provision, Build, Deploy, and Verify. From here you can see deployment process steps, its logs, and perform various actions like adding a custom domain, password-protect site etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8KFyuYIl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458776480/YPlYfVcic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8KFyuYIl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458776480/YPlYfVcic.png" alt="Hosting Envs &amp;amp; Process.png" width="880" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once deployment is successful you'll see the URL where an app is hosted, click on URL. If it is still not reflected you'll see the below screen otherwise your app will be served.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdQySWR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458726851/U3tmkV5Y-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QHdQySWR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662458726851/U3tmkV5Y-.png" alt="Preview Build Welcome.png" width="880" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SignUp
&lt;/h2&gt;

&lt;p&gt;Register a new user to access the site, Once you click Create account you'll receive a confirmation mail on your email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QWbKbdQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662461832292/iAK3vTnCn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QWbKbdQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662461832292/iAK3vTnCn.png" alt="SignUp.png" width="499" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the confirmation code that you received on the email to verify the email and complete registration, and then log in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gTPJFgPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662461757403/o1LH_y1Rr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gTPJFgPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662461757403/o1LH_y1Rr.png" alt="Confirmation Email.png" width="491" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try to attempt login with the wrong credential you will see amplify will throw a respective error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QDlmZgHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662462101825/L5awVqONu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QDlmZgHE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662462101825/L5awVqONu.png" alt="Failed Login.png" width="483" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  User Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Visit Amplify Studio Dashboard and Goto User Management Tab to view and manage Users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SwisWD0H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663580914120/WmeQ5SQTT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SwisWD0H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663580914120/WmeQ5SQTT.png" alt="Studio - User Mangement.png" width="880" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can also see and manage Users in Cognito Dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bvuBYgll--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663580799017/QJEJ1-bGK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bvuBYgll--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663580799017/QJEJ1-bGK.png" alt="Cognito Users.png" width="880" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Amplify API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Add Backend API
&lt;/h3&gt;

&lt;p&gt;To add backend service run the below command.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;It will ask for the type of service REST/GraphQL, endpoint, name of a resource, path, lambda source, lambda function name, runtime, template and other advanced settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--isTO0Z8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663581421320/YlO8PWwmF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--isTO0Z8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663581421320/YlO8PWwmF.png" alt="Add Node API.png" width="880" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Provision resources
&lt;/h2&gt;

&lt;p&gt;Once added locally push to the cloud for provisioning resources.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;It will create necessary resources like lambda instance, permissions, environment variables and configs, endpoints etc.&lt;/p&gt;

&lt;p&gt;You can create a function URL from Lambda Dashboard as below from the Function URL tab which is optional though.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xo1nxCWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662969954449/wzjyWBtNO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xo1nxCWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1662969954449/wzjyWBtNO.png" alt="Create Function URL.png" width="880" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove API and De-provision Resources
&lt;/h3&gt;

&lt;p&gt;To remove amplify API and lambda function run the below commands in the following order. First, you need to remove API and then the Lambda function because a function is dependent on API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify api remove apiexpress
amplify function remove mlwithamplifyexpress

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y1u9M6ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663581543027/MMSC4VoUh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y1u9M6ot--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663581543027/MMSC4VoUh.png" alt="Remove Function-API.png" width="880" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Summarization Logic
&lt;/h2&gt;

&lt;p&gt;We have added a lambda function to get a summary of the text, which takes input from the front end and processes text in lambda and another custom external API and returns a response to the front end. Here is the function code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */

const stopwords = ["i", "me", "my", "myself", "we", "our", "ours", "ourselves", "you", "your", "yours", "yourself", "yourselves", "he", "him", "his", "himself", "she", "her", "hers", "herself", "it", "its", "itself", "they", "them", "their", "theirs", "themselves", "what", "which", "who", "whom", "this", "that", "these", "those", "am", "is", "are", "was", "were", "be", "been", "being", "have", "has", "had", "having", "do", "does", "did", "doing", "a", "an", "the", "and", "but", "if", "or", "because", "as", "until", "while", "of", "at", "by", "for", "with", "about", "against", "between", "into", "through", "during", "before", "after", "above", "below", "to", "from", "up", "down", "in", "out", "on", "off", "over", "under", "again", "further", "then", "once", "here", "there", "when", "where", "why", "how", "all", "any", "both", "each", "few", "more", "most", "other", "some", "such", "no", "nor", "not", "only", "own", "same", "so", "than", "too", "very", "s", "t", "can", "will", "just", "don", "should", "now"];

function remove_stopwords(str) {
  let res = [];
  let words = str.split(" ");
  for (let i = 0; i &amp;lt; words.length; i++) {
    let word_clean = words[i].split(".").join("");
    if (!stopwords.includes(word_clean)) {
      res.push(word_clean);
    }
  }
  return res.join(" ");
}
exports.handler = async (event) =&amp;gt; {
  console.log("LAMBDA FUNTION INVOKED");
  const natural = require("natural");
  const fetch = require("node-fetch");
  let TfIdf = natural.TfIdf; // term-frequency inverse document frequency
  let tfidf = new TfIdf();
  const sent_tokenizer = new natural.SentenceTokenizer(); // sentence tokenizer
  const word_tokenizer = new natural.WordTokenizer(); // word tokenizer
  const body = JSON.parse(event.body);
  const doc = body.doc;
  console.log(`EVENT: ${JSON.stringify(event)}`);
  const sents = sent_tokenizer.tokenize(doc); // tokenize sentences
  let word_freq = {};
  // sentences without stopwords
  sents.forEach((sent) =&amp;gt; {
    tfidf.addDocument(remove_stopwords(sent));
  });
  // remove stopwords from document
  let stopWRDoc = remove_stopwords(doc);
  let wordArr = [];

  wordArr = word_tokenizer.tokenize(stopWRDoc);

  // find frequency of words
  wordArr.forEach((word) =&amp;gt; {
    if (!word_freq[word]) word_freq[word] = 0;
    if (wordArr.indexOf(word) === -1) word_freq[word] = 1;
    else word_freq[word] += 1;
  });

  // get maximum frequency
  const MAX_FREQ = Math.max(...Object.values(word_freq));

  // calculate weighted frequency
  Object.keys(word_freq).forEach((key) =&amp;gt; {
    word_freq[key] = word_freq[key] / MAX_FREQ;
  });

  // calculate sentence scores
  let sent_scores = {};

  const word_freq_keys = Object.keys(word_freq);
  sents.forEach((sent) =&amp;gt; {
    word_tokenizer.tokenize(sent.toLowerCase()).forEach((word) =&amp;gt; {
      if (word_freq_keys.indexOf(word) !== -1) {
        // shorter sentence for summary X length
        if (sent.split(" ").length &amp;lt; body.sentLength) {
          if (Object.keys(sent_scores).indexOf(sent) === -1) {
            sent_scores[sent] = word_freq[word];
          } else {
            sent_scores[sent] += word_freq[word];
          }
        }
      }
    });
  });
  // get summary
  const summary = await fetch("https://heapq-api.vercel.app/nlargest", {
    method: "POST",
    headers: { Accept: "application/json", "Content-Type": "application/json" },
    body: JSON.stringify({
      size: 5,
      sent_scores: sent_scores,
    }),
  }).then((res) =&amp;gt; res.json());

  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "*",
    },
    body: JSON.stringify({ flag: true, data: summary }),
  };
};

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

&lt;/div&gt;



&lt;p&gt;In this for text summarization and NLP(Natural Language Processing), we have used &lt;a href="https://github.com/NaturalNode/natural"&gt;natural&lt;/a&gt; library which does basic Sentence and Word tokenization, finding Term Frequency Inverse Document Frequency(TfIdf).&lt;/p&gt;

&lt;p&gt;In this, I have deployed the serverless function of Python library &lt;a href="https://docs.python.org/3/library/heapq.html"&gt;heapq&lt;/a&gt; API wrapper to find &lt;strong&gt;nlargest&lt;/strong&gt;. I need to separate this in Python due to the erroneous and lack of compatibility in the NodeJS ecosystem that I have tried.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://master.d32wxnkw2vu0dh.amplifyapp.com/"&gt;Visit the Demo Site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this, you can enter a large paragraph/document in the left input box and get a summary in the right pane.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Register yourself better for auth flow understanding or use Demo Credentials&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: &lt;strong&gt;amplifydemo&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Password: &lt;strong&gt;amplifydemo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_mF536GV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663586644556/7vv51rc3L.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_mF536GV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663586644556/7vv51rc3L.png" alt="Text Summary Demo.png" width="880" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this, you can customise sentence length, which is passed to the lambda function. Further can customize &lt;strong&gt;&lt;em&gt;heapq-nlargest&lt;/em&gt;&lt;/strong&gt; scoring which is currently 5 or change logic or something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debug Amplify App with CloudWatch
&lt;/h2&gt;

&lt;p&gt;To monitor your application, API and Lambda function you can use &lt;a href="https://aws.amazon.com/cloudwatch/"&gt;Amazon CloudWatch&lt;/a&gt;. In each deployment, a new log stream is created for easier access and monitoring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BqPp1sGU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137003545/lRCIhfIAa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BqPp1sGU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137003545/lRCIhfIAa.png" alt="Monitor Lambda Function.png" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see a list of lambda functions and a log of each deployment with a date and time based on the last event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r56iytPW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137127473/5GknjQHu_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r56iytPW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137127473/5GknjQHu_.png" alt="Deploy Cloudwatch Logs List.png" width="880" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case of an exception or error, you can get details info from CloudWatch logs that from where the error is occurring what it is and the cause of it. You can also see console logs here written in lambda functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4JiLnvqt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137063524/NwXy1cs8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4JiLnvqt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1663137063524/NwXy1cs8f.png" alt="Review CloudWatch Logs of Function/API.png" width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code and Local Setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/piyush-multiplexer/ml-with-amplify"&gt;https://github.com/piyush-multiplexer/ml-with-amplify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/piyush-multiplexer/heapq-api"&gt;https://github.com/piyush-multiplexer/heapq-api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the repository and go to the project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/piyush-multiplexer/ml-with-amplify.git
cd ml-with-amplify

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

&lt;/div&gt;



&lt;p&gt;You will amplify CLI to be installed for further operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @aws-amplify/cli

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

&lt;/div&gt;



&lt;p&gt;Configure Amplify Project&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;This will ask several questions and try to create an IAM role with the chosen region. Once Amplify is successfully configured run &lt;strong&gt;amplify push&lt;/strong&gt; to provision cloud resources and deploy your app. Visit your dashboard and see the preview URL to check if everything is working fine or not.&lt;/p&gt;

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

&lt;p&gt;So in the end we got to know how to use AWS Amplify CLI, Hosting, and UI for building full-stack applications with UI and authentication and set up Amplify REST API and lambda function for Text Summarization. I hope you find this article useful. Please leave a comment if any doubt. Like, comment, share and subscribe.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introduction to WebAssembly(Wasm) with Rust for Beginners</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Tue, 30 Aug 2022 07:31:00 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/introduction-to-webassemblywasm-with-rust-for-beginners-3f8n</link>
      <guid>https://dev.to/piyushmultiplexer/introduction-to-webassemblywasm-with-rust-for-beginners-3f8n</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;WebAssembly also known as WASM, is a technology that enables developers to run a set of code on a web browser with native-like performance. It is low-level assembly-like code that runs in the browser alongside JavaScript to achieve performance.&lt;/p&gt;

&lt;p&gt;As we all know in terms of performance lower level languages are the fastest like Binary, Assembly language, Higher level languages like C, C++, JavaScript, Python, Java, Ruby, Rust, Swift, and all that most of us use for daily purpose programming. Because these are more human-friendly than machines. There are a set of tools like interpreters, compilers, assemblers and others which convert these languages into machine code to make this understandable to real hardware.&lt;/p&gt;

&lt;p&gt;There are programming languages in which we can write our code and ship WebAssembly or Binary(WASM) files. Majorly used ones are Rust, TinyGo(Go), Emscripten(C/C++), and AssemblyScript. All of these languages are known for better performance and memory optimization.&lt;/p&gt;

&lt;p&gt;We will use Rust language as a compilation target for our demo of programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;Installation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install wasm-pack

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

&lt;/div&gt;



&lt;p&gt;In this &lt;strong&gt;cargo&lt;/strong&gt; is a Rust package manager just like &lt;strong&gt;npm&lt;/strong&gt; in node. In Rust, libraries are known as &lt;em&gt;crates&lt;/em&gt; like packages in Node. Here above command will install ( &lt;strong&gt;wasm-pack&lt;/strong&gt; )[&lt;a href="https://github.com/rustwasm/wasm-pack"&gt;https://github.com/rustwasm/wasm-pack&lt;/a&gt;] crate/lib in our system.&lt;/p&gt;

&lt;h5&gt;
  
  
  Initialization
&lt;/h5&gt;

&lt;p&gt;Create a new directory and go to that directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir wasm-rust-demo &amp;amp;&amp;amp; cd wasm-rust-demo

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

&lt;/div&gt;



&lt;h5&gt;
  
  
  Create Cargo Package.
&lt;/h5&gt;



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

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

&lt;/div&gt;



&lt;p&gt;Above command will create &lt;strong&gt;Cargo.toml&lt;/strong&gt; manifest file(similar like package.json in node) and &lt;strong&gt;src&lt;/strong&gt; directory with &lt;strong&gt;main.rs&lt;/strong&gt; basic rust file.&lt;/p&gt;

&lt;h5&gt;
  
  
  Edit Cargo.toml
&lt;/h5&gt;

&lt;p&gt;Paste the below code in the &lt;em&gt;Cargo.toml&lt;/em&gt; file. It defines crate-type as &lt;em&gt;cdylib&lt;/em&gt;, which is used when compiling a dynamic library which needs to be loaded from another language like JavaScript in our case. It includes dependency as &lt;a href="https://github.com/rustwasm/wasm-bindgen"&gt;&lt;strong&gt;wasm-bindgen&lt;/strong&gt;&lt;/a&gt;. This crate/package provides communication between Rust and JavaScript with other features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[package]
name = "wasm-rust-demo"
version = "0.1.0"
authors = ["Piyush Goyani &amp;lt;thesourcepedia@gmail.com&amp;gt;"]
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

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

&lt;/div&gt;



&lt;p&gt;Go to the &lt;em&gt;src/&lt;/em&gt; directory, rename &lt;strong&gt;main.rs&lt;/strong&gt; to &lt;strong&gt;lib.rs&lt;/strong&gt; , and add the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn calc(a: i32, b: i32, op: char) -&amp;gt; i32 {
    if op == '+' {
        return a + b;
    } else if op == '-' {
        return a - b;
    } else if op == '*' {
        return a * b;
    } else if op == '/' {
        return a / b;
    } else {
        return 0;
    }
}

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

&lt;/div&gt;



&lt;p&gt;Here we are defining a Rust function named &lt;strong&gt;calc&lt;/strong&gt; which takes three parameters, two numbers and 3rd for an operator to perform math action and return the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; wasm-pack build --target web

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

&lt;/div&gt;



&lt;p&gt;This command will compile Rust code to wasm and generate a &lt;strong&gt;pkg&lt;/strong&gt; directory which can be published to npm as a package and provides files which can be used in JavaScript communication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hggSbl7q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1661760197249/cQ9TyJShs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hggSbl7q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1661760197249/cQ9TyJShs.png" alt="Package Directory Content" width="316" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Error during build
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;[INFO]: Installing wasm-bindgen...&lt;/p&gt;

&lt;p&gt;Error: failed to download from &lt;a href="https://github.com/WebAssembly/binaryen/releases/download/version%5C_90/binaryen-version%5C_90-x86-linux.tar.gz"&gt;https://github.com/WebAssembly/binaryen/releases/download/version\_90/binaryen-version\_90-x86-linux.tar.gz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To disable &lt;code&gt;wasm-opt&lt;/code&gt;, add &lt;code&gt;wasm-opt = false&lt;/code&gt; to your package metadata in your &lt;code&gt;Cargo.toml&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Add this line in Cargo.toml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[package.metadata.wasm-pack.profile.release]
wasm-opt = false

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running WebAssembly/WASM Code.
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. By Loading Generated JS package
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
        import init, { calc } from "./pkg/wasm_with_rust.js"
        init().then(() =&amp;gt; {
            console.log(calc(10, 2, "+")) // 12
            console.log(calc(10, 2, "-")) // 8
            console.log(calc(10, 2, "*")) // 20
            console.log(calc(10, 2, "/")) // 5
        })
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;In this, we are loading a javascript file which is generated from &lt;strong&gt;wasm-pack&lt;/strong&gt; which does all the job of loading WebAssembly code and all complex memory-related stuff and export functions that we wrote in Rust(e.g &lt;em&gt;calc()&lt;/em&gt;) and &lt;em&gt;init()&lt;/em&gt; to initialize WebAssembly. In this, we are passing two integer parameters and 3rd is an operator which decides which math operation to perform.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. By Directly Loading &lt;strong&gt;.wasm&lt;/strong&gt; File
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
  WebAssembly.instantiateStreaming(fetch('./pkg/wasm_with_rust_bg.wasm'))
  .then((results) =&amp;gt; {
            const calc = results.instance.exports.calc
            console.log(calc(10, 2, 43)) // 12
            console.log(calc(10, 2, 45)) // 8
            console.log(calc(10, 2, 42)) // 20
            console.log(calc(10, 2, 47)) // 5
        })
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;In this, we are loading the &lt;strong&gt;wasm&lt;/strong&gt; binary file directly which is compiled from &lt;strong&gt;wasm-pack&lt;/strong&gt;. We are loading using &lt;em&gt;fetch&lt;/em&gt; and instantiate using &lt;strong&gt;instantiateStreaming()&lt;/strong&gt; method of &lt;strong&gt;WebAssembly&lt;/strong&gt; class available globally. Here we are passing the same parameter as above but as you can see 3rd parameter is numeric. That is ASCII value of operator respectively. Here we can not pass string value because are not passing it to JavaScript so it can further convert to Machine Code, but Passing it to directly WASM file.&lt;/p&gt;

&lt;p&gt;You can see the WASM Machine code that looks like below. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1BcwB1do--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1661762897772/2YH4xwZ0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1BcwB1do--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1661762897772/2YH4xwZ0d.png" alt="WASM Code" width="880" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/piyush-multiplexer/wasm-with-rust"&gt;Source&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources on WebAssembly
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webassembly.org/"&gt;WebAssembly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly"&gt;WebAssembly on MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Memory of WebAssembly is Linear. It is an expandable continuous buffer of unsigned bytes that can be read and stored from JavaSCript and WASM synchronously.&lt;/li&gt;
&lt;li&gt;Can import JavaScript functions and export custom function logic specified in WASM.&lt;/li&gt;
&lt;li&gt;Compiled to Binary file, Assembly-like language which gives native speed and performance in the browser.&lt;/li&gt;
&lt;li&gt;and many more based on requirements.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this tutorial, you get the basic idea of what is WebAssebly or wasm is, its purpose, make wasm binary from Rust Language and how to use it with JavaScript. I hope you enjoyed it give it a thumb, share, and subscribe. Have any doubts or thoughts share them in the comment section below. I am available &lt;a href="https://hashnode.com/@piyushgoyani"&gt;here.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Natural Language Processing with JavaScript using Compromise</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Fri, 26 Aug 2022 07:31:01 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/natural-language-processing-with-javascript-using-compromise-5hfc</link>
      <guid>https://dev.to/piyushmultiplexer/natural-language-processing-with-javascript-using-compromise-5hfc</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Natural Language Processing(NLP) is a mostly used and discussed concept worldwide. But in the field of programming languages like Python, R and are Java widely used for this concept because of their large library support and community. Today we will show how to use the concept of NLP using JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;If you are setting up Node Project use npm.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Add the following file in package.json if you face a module/import error.&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;On the client side with CDN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://unpkg.com/compromise"&amp;gt;&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Now let's import the library into the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nlp from "compromise";

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

&lt;/div&gt;



&lt;p&gt;Initialise the Instance of &lt;strong&gt;nlp&lt;/strong&gt; object with the demo string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const text = "I was there, suddenly raining starts. I am still sick!";
const doc = nlp(text);

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

&lt;/div&gt;



&lt;p&gt;This returns the document object of an input string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Tenses
&lt;/h4&gt;

&lt;p&gt;Convert document sentences to different tenses e.g past, present, and future tense.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(`Past Tense: ${doc.sentences().toPastTense().text()}`);
// Past Tense: I was there, suddenly raining starts. I was still sick!

console.log(`Present Tense: ${doc.sentences().toPresentTense().text()}`);
// Present Tense: I am there, suddenly raining starts. I am still sick!

console.log(`Future Tense: ${doc.sentences().toFutureTense().text()}`);
// Future Tense: I will be there, suddenly raining starts. I will be still sick!

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Negative Statement
&lt;/h4&gt;

&lt;p&gt;Convert regular or positive statements to negative statements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.sentences().toNegative().text())
// I was not there, suddenly raining starts. I am not still sick!

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Sentence Metadata
&lt;/h4&gt;

&lt;p&gt;Let's look into the detail or meta data of the sentence. It returns array of objects for every sentence, which includes, text string, sentence detail(subject, verb, predicate, noun etc), and terms array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.sentences().json())
// [
// ({
// text: "I was there, suddenly raining starts.",
// terms: [[Object], [Object], [Object], [Object], [Object], [Object]],
// sentence: { subject: "i", verb: "was", predicate: "there starts" },
// },
// {
// text: "I am still sick!",
// terms: [[Object], [Object], [Object], [Object]],
// sentence: { subject: "i", verb: "am still", predicate: "sick" },
// })
// ]

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Metadata Details
&lt;/h4&gt;

&lt;p&gt;As we see above, there is an array of objects named &lt;strong&gt;terms&lt;/strong&gt; for every sentence, lets look inside that. It returns detail of every word and its attributes like text, pre/post symbols, tags, index, id, chunks, and dirty flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.sentences().json()[1].terms);
// [
// {
// text: 'I',
// pre: '',
// post: ' ',
// tags: ['Noun', 'Pronoun'],
// normal: 'i',
// index: [1, 0],
// id: 'i|00700100W',
// chunk: 'Noun',
// dirty: true
// },
// {
// text: 'am',
// pre: '',
// post: ' ',
// tags: ['Verb', 'Copula', 'PresentTense'],
// normal: 'am',
// index: [1, 1],
// id: 'am|00800101O',
// chunk: 'Verb',
// dirty: true
// },
// {
// text: 'still',
// pre: '',
// post: ' ',
// tags: ['Adverb'],
// normal: 'still',
// index: [1, 2],
// id: 'still|00900102C',
// dirty: true,
// chunk: 'Verb'
// },
// {
// text: 'sick',
// pre: '',
// post: '!',
// tags: ['Adjective'],
// normal: 'sick',
// index: [1, 3],
// id: 'sick|00A00103B',
// dirty: true,
// chunk: 'Adjective'
// }
// ]

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adjectives
&lt;/h4&gt;

&lt;p&gt;Finding adjectives from the text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.adjectives().text());
// sick

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adverbs
&lt;/h4&gt;

&lt;p&gt;Looking for Adverbs that are describing the Adjectives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.adjectives().adverbs().text());
// still

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adjectives Metadata
&lt;/h4&gt;

&lt;p&gt;Same as a sentence, adjectives also have metadata that can retrieve as below, both have different formats of results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.adjectives().json());
// [
// {
// text: 'sick!',
// terms: [[Object] ],
// normal: 'sick!',
// adjective: {
// adverb: 'sickly',
// noun: 'sickness',
// superlative: 'sickest',
// comparative: 'sicker'
// }
// }
// ]

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Pre Post Sentences
&lt;/h4&gt;

&lt;p&gt;Here we will add a specific symbol in starting(/) and ending() of each sentence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.pre("/").text())
console.log(doc.post("\\ ").text())

// /I was there, suddenly raining starts. /I am still sick!
// /I was there, suddenly raining starts\ /I am still sick\

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Whitespace
&lt;/h4&gt;

&lt;p&gt;Add hyphens to white spaces in sentences with the inbuilt &lt;strong&gt;hyphenate&lt;/strong&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(doc.hyphenate().text())
// I-was-there-suddenly-raining-starts. I-am-still-sick!

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Number Game
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const str = "Price of an Apple is $1.5, per KG may around 6 to 7.5 USD";
const numDoc = nlp(str);

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

&lt;/div&gt;



&lt;p&gt;Parsing numbers in a given string and getting details with prefixes and suffixes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(numDoc.numbers().parse());
// [
// { prefix: "$", num: 1.5, suffix: "", hasComma: false, unit: "" },
// { prefix: "", num: 6, suffix: "", hasComma: false, unit: "" },
// { prefix: "", num: 7.5, suffix: "", hasComma: false, unit: "usd" },
// ];

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

&lt;/div&gt;



&lt;p&gt;Increment/Decrement numbers in a sentence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(numDoc.numbers().increment().text());
// $2.5, 7 8.5

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

&lt;/div&gt;



&lt;p&gt;Convert numbers or digits to text format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(numDoc.numbers().toText().text());
// one point five dollars, six seven point five

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/spencermountain/compromise"&gt;Compromise lib Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/piyush-multiplexer/js-4-nlp-ml-ai"&gt;Source Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Thanks for reading. In this article, we get a basic idea of how to process textual data for NLP with JavsSCript using &lt;strong&gt;compromise&lt;/strong&gt; library. These were very basic uses of a library you can review its documentation further. If you enjoyed the article give it a thumb, subscribe and stay tuned for more.&lt;/p&gt;

</description>
      <category>nlp</category>
      <category>javascript</category>
      <category>compromise</category>
      <category>node</category>
    </item>
    <item>
      <title>Dedicated and Shared Web Worker with Performance Testing</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Thu, 18 Aug 2022 11:39:52 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/dedicated-and-shared-web-worker-with-performance-testing-587</link>
      <guid>https://dev.to/piyushmultiplexer/dedicated-and-shared-web-worker-with-performance-testing-587</guid>
      <description>&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Web Workers are threads attached in Browser and run on the client side. It runs in a separate space from the main application thread. Simply It gives the ability to write multi-threaded Javascript applications. It is generally used to do heavy lifting tasks(in terms of computational time), e.g process huge data from API, calculations, batching of real-time chart data before drawing in the background.&lt;/p&gt;

&lt;p&gt;Web Workers perform all processes in the Worker thread aka separate environment which is separate from the main JavaScript thread without blocking UI or affecting performance thus does not have access to DOM, &lt;em&gt;window&lt;/em&gt; and &lt;em&gt;document&lt;/em&gt; objects, and for the same reason, it can not simply manipulate DOM.&lt;/p&gt;

&lt;p&gt;The life span of a Worker is limited to a browser tab, when a browser tab is closed Worker also dies. The data are passed between Worker and the main thread via messages. To send data &lt;code&gt;postMessage()&lt;/code&gt; method is used and to listen to messages &lt;code&gt;onmessage&lt;/code&gt; event is used on both sides.&lt;/p&gt;

&lt;p&gt;A single web page/app can have more than one Web Worker regardless of the number of tabs. It can be Shared or Dedicated workers. We'll go through demo examples for both workers and use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;In this demo, there are two examples, in first you can test that the 50k array is being sorted with bubble sort algorithm with and without Web Worker(Dedicated) and see the difference between both. Second, you can test Shared Worker which is used by two client sources for similar functionality. Both workers use Network APIs for the processing which is made in Node/ExpressJS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jsworkers.herokuapp.com/"&gt;Preview Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/piyush-multiplexer/javascript-workers"&gt;Source of Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EE8i3uqu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712197362/unXvUYykq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EE8i3uqu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712197362/unXvUYykq.png" alt="Demo Page" width="880" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dedicated Workers
&lt;/h3&gt;

&lt;p&gt;Dedicated Workers can only establish a single connection. It can be initialized using the following syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let worker = new Worker("worker.js");

// receive data from web worker sent via postMessage()
worker.onmessage = function (e) {
  console.log(e.data);
}

// send data to web worker
.postMessage("start")

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

&lt;/div&gt;



&lt;p&gt;To receive data &lt;strong&gt;onmessage&lt;/strong&gt; event is used and to pass data &lt;strong&gt;postMessage&lt;/strong&gt; method is used. In this demo, we have used a Dedicated worker to Bubble Sort 50k length of array data. In UI there are two options for sorting with or without Web Workers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Without Web Worker
&lt;/h4&gt;

&lt;p&gt;When the user clicks the without web worker option, the script starts and gets data from the API of the 50k array and starts sorting in a main, during this you may see a frozen progress bar, and the rest things are stuffed like not able to select the text, the mouse pointer changes to the cursor and other UI blocking effects because it is performing a heavy task to sort a large array. When sorting is done you'll see processing time and an animated section regarding the process below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tSC8X4Wx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712535233/ZrXRkLMaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tSC8X4Wx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712535233/ZrXRkLMaa.png" alt="Without Web Worker" width="512" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  With Web Worker
&lt;/h4&gt;

&lt;p&gt;When the user clicks the web worker option, the worker initiate and gets data from the API of the 50k array and starts sorting in a separate thread, during this you can see a progress bar and no UI blocking like text-selection and cursor etc. Everything is smooth. When sorting Done you'll see processing time and an animated section regarding the process below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PfkrcOiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712245611/hDnLKptcX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PfkrcOiI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712245611/hDnLKptcX.png" alt="With Web Worker" width="517" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So Web Workers overcome this problem. Here is the &lt;strong&gt;&lt;em&gt;index.html&lt;/em&gt;&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;div id="wrap"&amp;gt;
        &amp;lt;div class="container"&amp;gt;
            &amp;lt;div class="row pt-3"&amp;gt;
                &amp;lt;div class="col"&amp;gt;
                    &amp;lt;h2&amp;gt;Dedicated Worker&amp;lt;/h2&amp;gt;
                    &amp;lt;div class="text-secondary h4"&amp;gt;
                        Sorting Array with Bubble Sort(50k)
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div&amp;gt;
                        &amp;lt;button class="btn btn-large btn-primary" onclick="nonWebWorker();"&amp;gt;Without Web Worker&amp;lt;/button&amp;gt;
                        &amp;lt;button class="btn btn-large btn-success" onclick="withWebWorker();"&amp;gt;With Web Worker&amp;lt;/button&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div id="progressbar" class="progress hide"&amp;gt;
                        &amp;lt;div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
                            aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"&amp;gt;&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div id="resultBox" class="hide bg-info rounded px-2"&amp;gt;
                        &amp;lt;p class="muted"&amp;gt;
                            Array sorted in:
                        &amp;lt;/p&amp;gt;
                        &amp;lt;h1 id="timespent"&amp;gt;&amp;lt;/h1&amp;gt;
                        &amp;lt;p id="withoutWW" class="output hide"&amp;gt;
                            As you can see, without Web Worker, your browser may be able to sort the 50K Array but you
                            can't work with your browser while sorting and also your browser won't render anything until
                            sorting ends, that's why you can't see the animated progress bar on the page.
                        &amp;lt;/p&amp;gt;
                        &amp;lt;p id="withWW" class="output hide"&amp;gt;
                            Your browser sorted 50K Array without any crash or lagging because your browser supports
                            Web Worker. When you do a job with Web Worker, it's just like when you run a program in
                            another thread. Also, you can see the animated progress bar while sorting.
                        &amp;lt;/p&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="col-1"&amp;gt;
                    &amp;lt;div class="vr h-100"&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;script src="./utils.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Dedicated Worker file &lt;strong&gt;&lt;em&gt;worker.js&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;onmessage = async function (e) {
  if (e.data[0] === "start") {
    let a = [];

    async function getData() {
      return fetch(`${e.data[1]}/getData`)
        .then((res) =&amp;gt; res.json())
        .then((data) =&amp;gt; {
          a = data;
        });
    }

    function bubbleSort(a) {
      let swapped;
      do {
        swapped = false;
        for (let i = 0; i &amp;lt; a.length - 1; i++) {
          if (a[i] &amp;gt; a[i + 1]) {
            let temp = a[i];
            a[i] = a[i + 1];
            a[i + 1] = temp;
            swapped = true;
          }
        }
      } while (swapped);
    }
    let start = new Date().getTime();
    getData()
      .then(() =&amp;gt; {
        bubbleSort(a);
      })
      .then(() =&amp;gt; {
        let end = new Date().getTime();
        let time = end - start;
        postMessage(time);
      });
  }
};

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Shared Workers
&lt;/h3&gt;

&lt;p&gt;The Shared Worker can establish multiple connections as they are accessible by multiple scripts even in separate windows, iframes(demo) or workers. It can be spawned using the below syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let sharedWorker = new SharedWorker("shared-worker.js");
sharedWorker.port.postMessage("begin");
sharedWorker.port.onmessage = function (e) {
  console.log(e.data)
}

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

&lt;/div&gt;



&lt;p&gt;In Shared Worker similar concept apply as Worker for data passing but via &lt;strong&gt;port&lt;/strong&gt; object(explicit object) which is done implicitly in dedicated workers for communication. In this demo, there is a Shared Worker which does multiply/square of numbers. It is used in two places. The first is on the main page and the second is on another HTML page which is included in the main page via IFRAME. On the main page user input two number for multiplication and passes them to Worker and get multiplied output as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7ltckabz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712407310/lApZw3uQi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7ltckabz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712407310/lApZw3uQi.png" alt="Shared Workers Main" width="516" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second case, the user inputs single number input which is given to the same Shared Worker and gets a squared input number as a result. Now within the worker, it takes input as the number and calls API to do Math Operation and returns the result as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vaSZa3bS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712434939/jhp3h2o6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vaSZa3bS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660712434939/jhp3h2o6i.png" alt="Shared Workers iFrame" width="410" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Main HTML file to load IFRAME &lt;strong&gt;&lt;em&gt;index.html&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;lt;div class="col"&amp;gt;
                    &amp;lt;h2&amp;gt;Shared Worker&amp;lt;/h2&amp;gt;
                    &amp;lt;div class="text-secondary h4"&amp;gt;
                        Multiply/Square Numbers with Shared Resource
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div&amp;gt;
                        &amp;lt;input type="text" id="number1" class="form-control" placeholder="Enter number 1" /&amp;gt;
                        &amp;lt;input type="text" id="number2" class="form-control mt-1" placeholder="Enter number 2" /&amp;gt;
                        &amp;lt;input type="button" class="btn btn-dark mt-2" value="Calculate" onclick="multiply();" /&amp;gt;
                        &amp;lt;p class="result1 text-success pt-2"&amp;gt;&amp;lt;/p&amp;gt;
                        &amp;lt;iframe id="iframe" src="shared.html"&amp;gt;&amp;lt;/iframe&amp;gt;
                    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Second HTML file &lt;strong&gt;&lt;em&gt;shared.html&lt;/em&gt;&lt;/strong&gt; which load in IFRAME in parent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;
        const endpoint = window.origin;
        if (typeof (Worker) === "undefined") {
            alert("Oops, your browser doesn't support Web Worker!");
        }

        function getSquare() {
            let third = document.querySelector("#number3");
            let squared = document.querySelector(".result2");

            if (!!window.SharedWorker) {
                let myWorker = new SharedWorker("shared-worker.js");
                myWorker.port.postMessage([third.value, third.value, window.origin]);
                myWorker.port.onmessage = function (e) {
                    squared.textContent = e.data;
                };
            }
        }
    &amp;lt;/script&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        &amp;lt;h1&amp;gt;
            Shared Web Worker(iframe)
        &amp;lt;/h1&amp;gt;
        &amp;lt;div class="row"&amp;gt;
            &amp;lt;div class="col"&amp;gt;
                &amp;lt;input type="text" id="number3" class="form-control" placeholder="Enter a number" /&amp;gt;
                &amp;lt;input type="button" id="btn" class="btn btn-primary" value="Submit" onclick="getSquare()" /&amp;gt;
                &amp;lt;p class="result2"&amp;gt;&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Here is &lt;strong&gt;&lt;em&gt;shared-worker.js&lt;/em&gt;&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;onconnect = function (e) {
  let port = e.ports[0];

  port.onmessage = function (e) {
    fetch(`${e.data[2]}/multiply?number1=${e.data[0]}&amp;amp;number2=${e.data[1]}`)
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        port.postMessage([data.result]);
      });
  };
};

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

&lt;/div&gt;



&lt;p&gt;Utility functions file &lt;strong&gt;&lt;em&gt;utils.js&lt;/em&gt;&lt;/strong&gt; that handles worker-related stuff.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const endpoint = window.origin;
if (typeof Worker === "undefined") {
  alert("Oops, your browser doesn't support Web Worker!");
}

function nonWebWorker() {
  cleanWindowAndStart();
  let a = [];
  async function getData() {
    return fetch(`${endpoint}/getData`)
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        a = data;
      });
  }

  function bubbleSort(a) {
    let swapped;
    do {
      swapped = false;
      for (let i = 0; i &amp;lt; a.length - 1; i++) {
        if (a[i] &amp;gt; a[i + 1]) {
          let temp = a[i];
          a[i] = a[i + 1];
          a[i + 1] = temp;
          swapped = true;
        }
      }
    } while (swapped);
  }

  let start = new Date().getTime();
  getData()
    .then(() =&amp;gt; {
      bubbleSort(a);
    })
    .then(() =&amp;gt; {
      let end = new Date().getTime();
      let time = end - start;
      afterStop(time, false);
    });
}

function withWebWorker() {
  cleanWindowAndStart();
  let worker = new Worker("worker.js");
  worker.onmessage = function (e) {
    afterStop(e.data, true);
  };
  worker.postMessage(["start", endpoint]);
}

function cleanWindowAndStart() {
  $("#resultBox").hide(500);
  $("#withWW").hide();
  $("#withoutWW").hide();
  $("#progressbar").addClass("d-flex").show(500);
}

function afterStop(spentTime, mode) {
  $("#timespent").html(spentTime + "ms");
  $("#progressbar")
    .hide(500, function () {
      mode ? $("#withWW").show() : $("#withoutWW").show();
      $("#resultBox").show(500);
    })
    .removeClass("d-flex");
}

function multiply() {
  let first = document.querySelector("#number1");
  let second = document.querySelector("#number2");

  let multiplied = document.querySelector(".result1");

  if (!!window.SharedWorker) {
    let myWorker = new SharedWorker("shared-worker.js");

    myWorker.port.postMessage([first.value, second.value, endpoint]);

    myWorker.port.onmessage = function (e) {
      multiplied.textContent = e.data;
    };
  }
}

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

&lt;/div&gt;



&lt;p&gt;Node/Express API &lt;strong&gt;&lt;em&gt;server.js&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;app.get("/getData", (req, res) =&amp;gt; {
  res.send(
    Array(50000)
      .fill(0)
      .map(() =&amp;gt; Math.floor(Math.random() * 100))
  );
});

app.get("/multiply", (req, res) =&amp;gt; {
  const multiply = req.query.number1 * req.query.number2;
  const result = isNaN(multiply) ? "Invalid input" : multiply;
  res.send({ result });
});

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance Testing
&lt;/h3&gt;

&lt;p&gt;Now time for numbers. Let's test our Sorting demo with Chrome Performance Test in Browser DevTools. We will record and profile both with and without web workers so we can differentiate performance and resource utilization.&lt;/p&gt;

&lt;h4&gt;
  
  
  Without Web Worker
&lt;/h4&gt;

&lt;p&gt;Open Dev Tools and navigate to the Performance tab and start recording. Once recording starts in UI click on the Without Worker button in Dedicated Worker Section and waits till sorting is done. Once you see the result stop recording and the preview will be there as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GS2TeTIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735436151/cZCgPLB0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GS2TeTIM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735436151/cZCgPLB0p.png" alt="Chrome Perf Profile - Without Worker" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an overview of the Performance tab which looks a little complicated. We'll use some of these for over understanding of the use case. In the first section, you can see the Frame rate, Network, CPU and Memory utilization chart. Below is the Network section where requests are recorded with the timeline. Below is Main Section which shows all tasks, macro tasks, functions and thread-related information that was executed in the tab during that time. You can click for a detailed view of each. Below is the CPU activity breakdown in a pie chart, which show the type of tasks with the time taken.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wMmkoOFr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735585245/yLr8Kghmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wMmkoOFr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735585245/yLr8Kghmi.png" alt="Chrome Perf Profile - Without Worker Activity" width="880" height="297"&gt;&lt;/a&gt;This is a detailed activity view of the &lt;strong&gt;bubbleSort&lt;/strong&gt; script, and here you can see that this function consumes most of the resources and time in a thread(96.5% - 5663 ms) and other processes like rendering dom and manipulation, network calls consumed rest of all. You can save your profile if you want or delete it.&lt;/p&gt;

&lt;h4&gt;
  
  
  With Web Worker
&lt;/h4&gt;

&lt;p&gt;Now once you test with Without Worker Profiling, start with With Worker button. The process is the same, start recording -&amp;gt; click on With Web Worker button -&amp;gt; stop recording once sorting is done. Before that make sure the Performance tab is cleared and you will see a similar result as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sNDkBYb4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735845932/Tx2kntnvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sNDkBYb4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735845932/Tx2kntnvq.png" alt="Chrome Perf Profile - With Worker" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you look in the profile With Workers in Performance tab you'll see a significant difference from the previous summary of the consumed time by task type. Here the script is consume very less time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WEukbUV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735666429/OgVJnlVqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WEukbUV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1660735666429/OgVJnlVqQ.png" alt="Chrome Perf Profile - With Worker Activity" width="880" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, with a worker as you can see in activity details, you won't see &lt;strong&gt;bubbleSort&lt;/strong&gt; or any other script taking a long time this breakdown is of the main thread but sorting is done in a worker thread so it doesn't affect the main thread resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages &amp;amp; Limitations with Usecases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Can be used to perform CPU-intensive tasks without blocking UI.&lt;/li&gt;
&lt;li&gt;Has access to fetch, so can communicate over Netowork to make API requests.&lt;/li&gt;
&lt;li&gt;Doesn't have access to DOM, so can't manipulate therefore, tasks like canvas, images, SVG, video or any element-related drawing/direct manipulation is not possible.&lt;/li&gt;
&lt;li&gt;Can be used in Real-time data processing in the Stock market and related fields e.g Crypto, and NFT.&lt;/li&gt;
&lt;li&gt;To process large data-sets like DNA and Genetics&lt;/li&gt;
&lt;li&gt;Media manipulation in the background e.g image compress/decompress, video etc.&lt;/li&gt;
&lt;li&gt;Can be used to process textual data in the background e.g NLP&lt;/li&gt;
&lt;li&gt;Caching: Prefetching data for later use&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this article, we have got the basic idea of Web Workers including Dedicated and Shared Workers and How they affect user experience if used properly in a project. We also debug it with the Chrome DevTools Performance tab as proof of the consumed resources that our app consumed.&lt;/p&gt;

&lt;p&gt;If you enjoyed the article and found it useful give it a thumb. Let us know your thoughts on this in the comment section below. You can find me on &lt;a href="https://twitter.com/thesourcepedia"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Build ChatBot with ChatterBot and Python - Part 1</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Mon, 01 Aug 2022 09:20:46 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/build-chatbot-with-chatterbot-and-python-part-1-13e9</link>
      <guid>https://dev.to/piyushmultiplexer/build-chatbot-with-chatterbot-and-python-part-1-13e9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ChatterBot is a machine-learning based conversational dialogue engine build in Python which makes it possible to generate responses based on collections of known conversations. The language-independent design of ChatterBot allows it to be trained to speak any language. Initially, it has no knowledge, then based on training and communication it tries to respond to the user's query accurately. It matches the closest matching response by searching a statement that matches the input and how frequently the response is used. These things are highly customizable with logic adapters, training processes, preprocessors, filters, and other custom behaviour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;We'll install a &lt;code&gt;chatterbot&lt;/code&gt; package with pip. So first, open your terminal and type the following command with the appropriate Python version. Here I'm using &lt;em&gt;v3.7.10&lt;/em&gt; specifically.&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 chatterbot

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

&lt;/div&gt;



&lt;p&gt;Check if the installation is successful, run the below command:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Once done with installation let's start with a basic example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Bot
&lt;/h2&gt;

&lt;p&gt;First, create a file named &lt;em&gt;greet_bot.py&lt;/em&gt;. import ChatBot class from chatterbot library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from chatterbot import ChatBot

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

&lt;/div&gt;



&lt;p&gt;Create a new chatbot named "&lt;em&gt;GreetBot&lt;/em&gt;", you can give any name you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chatbot = ChatBot("GreetBot")

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Training your Bot
&lt;/h2&gt;

&lt;p&gt;Import ListTrainer from sets of available trainers to train bot with greet data so it can respond to our inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from chatterbot.trainers import ListTrainer

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

&lt;/div&gt;



&lt;p&gt;Create trainer instance of ListTrainer with chatbot parameter, and train with list of sample greeting data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trainer = ListTrainer(chatbot)
train_data = [
    "Hello",
    "Hi",
    "Hi, how are you?",
    "I'm doing great.",
    "Greetings!",
    "How do you do?",
    "Great, thanks for asking!",
    "What's up"
] 
trainer.train(train_data)

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Retrieve response from Bot
&lt;/h2&gt;

&lt;p&gt;To retrieve a response from trained bot use &lt;strong&gt;get_response&lt;/strong&gt; method of bot object with input parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;response = chatbot.get_response('hi')
print(response)

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from chatterbot import ChatBot
from chatterbot.trainers import ListTrainer

chatbot = ChatBot('GreetBot')

trainer = ListTrainer(chatbot)

train_data = [
    "Hello",
    "Hi",
    "Hi, how are you?",
    "I'm doing great.",
    "Greetings!",
    "How do you do?",
    "Great, thanks for asking!",
    "What's up"
]

trainer.train(train_data)

response = chatbot.get_response('Hi')
print(response)

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

&lt;/div&gt;



&lt;p&gt;To run a bot, run the script &lt;em&gt;greet_bot.py&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;python greet_bot.py

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OT64Y5uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659516328405/lgy1F58vB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OT64Y5uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659516328405/lgy1F58vB.png" alt="image.png" width="880" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Thank You for reading this article. I hope this helps in some ways and get a basic idea of how to get started with bot building with Python and the Chatterbot library. This was a very basic explanation and demo. Share, Like, Subscribe and stay tuned for the same and other bot-building tutorials.&lt;/p&gt;

</description>
      <category>python</category>
      <category>bot</category>
      <category>chatbot</category>
      <category>chatterbot</category>
    </item>
    <item>
      <title>Setup Ghost Webhook for Custom Email Newsletter</title>
      <dc:creator>Piyush Goyani</dc:creator>
      <pubDate>Fri, 29 Jul 2022 05:24:59 +0000</pubDate>
      <link>https://dev.to/piyushmultiplexer/setup-ghost-webhook-for-custom-email-newsletter-2iop</link>
      <guid>https://dev.to/piyushmultiplexer/setup-ghost-webhook-for-custom-email-newsletter-2iop</guid>
      <description>&lt;p&gt;Hello people,&lt;/p&gt;

&lt;p&gt;This guide is to set up and send the newsletter to subscribers in &lt;a href="https://ghost.org"&gt;Ghost&lt;/a&gt; cms with Custom Webhook support. As you know Ghost provides only integration of &lt;a href="https://www.mailgun.com"&gt;Mailgun&lt;/a&gt; and they don't have a free tier or simply say costly pricing structure for me.&lt;/p&gt;

&lt;p&gt;So I needed an alternate approach from many of &lt;a href="https://ghost.org/docs/faq/mailgun-newsletters/"&gt;proposed solutions&lt;/a&gt;. I have tried with Zappier Gmail integration but it was causing the same issue that will occur in this setup too. I opened a discussion regarding that in &lt;a href="https://forum.ghost.org/t/ghost-newsletter-mail-for-any-email-service-integration/30779"&gt;Ghost Forum&lt;/a&gt; but no response till now.&lt;/p&gt;

&lt;p&gt;Anyway, We will try a custom solution with Webhooks. There any many webhooks available in Ghost that you can build your custom solution or integration as needed. This guide follows a self-hosted Ghost instance on a cloud server, not a managed one. Let's begin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Ghost Webhooks
&lt;/h3&gt;

&lt;p&gt;Refer to this &lt;a href="https://ghost.org/docs/webhooks/"&gt;Offical Webhook Doc - Ghost&lt;/a&gt; to understand and see a list of available webhooks in Ghost, their triggers and which to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create New Integration
&lt;/h3&gt;

&lt;p&gt;From Ghost Admin, Goto &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Integrations&lt;/strong&gt;. Click on the &lt;strong&gt;Add Custom integration&lt;/strong&gt; Button and you will see the below dialogue. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uyn0Uefk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659003388539/jW_Nu64a_6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uyn0Uefk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659003388539/jW_Nu64a_6.png" alt="image.png" width="636" height="294"&gt;&lt;/a&gt;In this dialogue give the name of your integration(e.g Custom Email hooks) or whatever you want like Newsletter something and click Create.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure your Integration
&lt;/h3&gt;

&lt;p&gt;When you click on &lt;strong&gt;Create&lt;/strong&gt; you will be redirected to the configuration page, where you have two sections. Configuration and Webhooks.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.1 Basic Configuration
&lt;/h4&gt;

&lt;p&gt;In the Configuration section, you can add/update things like Name, Description, and Icon of Integration. Other important things are credentials like Content API key, Admin API key and API URL as below. You can regenerate API keys if you want in case of loss/compromise. &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Um_lK30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659003941473/m1IAinlC8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Um_lK30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659003941473/m1IAinlC8.png" alt="image.png" width="880" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3.2 Add New webhook
&lt;/h4&gt;

&lt;p&gt;Click on the &lt;strong&gt;Add webhook&lt;/strong&gt; button to create a new webhook where you'll see the following popup. Add &lt;strong&gt;Name&lt;/strong&gt; of the hook, Select &lt;strong&gt;Event&lt;/strong&gt; e.g I have selected &lt;em&gt;Page Published&lt;/em&gt; event from many available because we want to trigger an event when a page is published and send a mail with our custom logic and finally set &lt;strong&gt;Target URL&lt;/strong&gt; where you want to pass webhook payload which will further process it and send mail, it can be any running server/less API. Click on Create and your webhook should be created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Du-LyPo3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659004081521/9Ax-bQ76I.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Du-LyPo3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659004081521/9Ax-bQ76I.png" alt="image.png" width="444" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3 Review/Update Webhooks
&lt;/h4&gt;

&lt;p&gt;When you create a webhook you will see it is listed here, all your webhooks are listed here in this specific integration. From here you can edit/edit webhook, and see when was last it was triggered and other basic information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M0iR6Li9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659004176856/mqWwQChmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M0iR6Li9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1659004176856/mqWwQChmp.png" alt="image.png" width="880" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As Ghost is tightly coupled with Mailgun, and in most releases, their features are also connected to it e.g during publishing a post you can't send Newsletter if Mailgun is not configured. &lt;/li&gt;
&lt;li&gt;With this setup, you won't be able to see stats of emails/newsletters-related stuff, If I say simply that you can only send emails when specified webhook triggers.&lt;/li&gt;
&lt;li&gt;As I said earlier, when you send a mail with this you'll lose CSS/UI in the mail, but you can build an email template for this by referring to internal logic in Ghost.&lt;/li&gt;
&lt;li&gt;In this, my newsletter emails are sent using NodeMailer with Gmail(SMTP), which should not be used in production, but implement queue management or an alternate approach on the server side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading this article, I hope this guide was informative and useful to you, please like/share and leave your feedback.&lt;/p&gt;

</description>
      <category>ghost</category>
      <category>email</category>
      <category>newsletter</category>
      <category>webhooks</category>
    </item>
  </channel>
</rss>
