<?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>Forem: Ramki Pitchala</title>
    <description>The latest articles on Forem by Ramki Pitchala (@ramko9999).</description>
    <link>https://forem.com/ramko9999</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%2F613336%2Fe2fed54e-f6e8-47b0-a055-7d822c0663eb.jpeg</url>
      <title>Forem: Ramki Pitchala</title>
      <link>https://forem.com/ramko9999</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ramko9999"/>
    <language>en</language>
    <item>
      <title>Build a Dynamic Portfolio With the Github API</title>
      <dc:creator>Ramki Pitchala</dc:creator>
      <pubDate>Thu, 22 Apr 2021 21:13:37 +0000</pubDate>
      <link>https://forem.com/ramko9999/build-a-dynamic-portfolio-with-the-github-api-3eh9</link>
      <guid>https://forem.com/ramko9999/build-a-dynamic-portfolio-with-the-github-api-3eh9</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/swlh/build-a-dynamic-portfolio-with-the-github-api-6d74081e5164" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;. If you prefer reading it from there, please do check it out.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;With the advent of countless templates and web page design applications, the task of creating a personal portfolio transitioned from a painful endeavor into a painless task. &lt;/p&gt;

&lt;p&gt;However, the act of constantly updating the hard-coded information and rebuilding and redeploying your portfolio turns into a tiresome burden.&lt;/p&gt;

&lt;p&gt;In this tutorial, I will show you how I integrated the Github API into my portfolio to pull the most recent project information, solving the issue of directly updating and redeploying my portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Before we build the solution, let’s first understand the core idea and configure Github to ease the integration.&lt;/p&gt;

&lt;p&gt;First, let’s talk about the Github repositories. To elaborate, I house my projects in the repositories themselves: I host the source code, keep detailed descriptions, and maintain links to demo gifs or images.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3536%2F1%2Aqb3hbCXT2CI6gHVMqyjOSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3536%2F1%2Aqb3hbCXT2CI6gHVMqyjOSw.png" alt="Link to the repository [https://github.com/Ramko9999/Pathfinding-Visualizer](https://github.com/Ramko9999/Pathfinding-Visualizer)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This repository houses my Path Finding Visualizer project. &lt;/p&gt;

&lt;p&gt;In the right side, the section outlined in blue contains the description of the project. On the other hand, the section outlined in red has a link to the demo. Finally, the section outlined in black contains topics associated with the project. &lt;/p&gt;

&lt;p&gt;To sum it all up, the Github &lt;a href="https://docs.github.com/en/rest" rel="noopener noreferrer"&gt;API&lt;/a&gt; will return the above fields upon an HTTP request to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /users/{username}/repos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This &lt;a href="https://docs.github.com/en/rest/reference/repos#list-repositories-for-a-user" rel="noopener noreferrer"&gt;endpoint&lt;/a&gt; will return a list of public repositories for a user. &lt;/p&gt;

&lt;p&gt;Here is what the return json object looks likes for the Path Finding Visualizer repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2376%2F1%2AY-rqrLmYUNFXvzhtZaCksA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2376%2F1%2AY-rqrLmYUNFXvzhtZaCksA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although it is a bit difficult to see, the API returned the fields we need: description, homepage, and topics. &lt;/p&gt;

&lt;p&gt;This is fantastic news, since it shows that we can store and retrieve information from our repositories.&lt;/p&gt;

&lt;p&gt;Let’s now work on configuring Github to simplify the integration.&lt;/p&gt;

&lt;p&gt;All we need to do is generate a personal access token in the developer settings. We will use the personal access token to authenticate our requests to the Github API so we can take advantage of the generous rate limits.&lt;/p&gt;

&lt;p&gt;First, navigate to your profile settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AOVJwlVGOfwlSQl9lN2sR4A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2AOVJwlVGOfwlSQl9lN2sR4A.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From your profile settings, navigate to the developer settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Al4B3diZ1wSWr59daXuhAIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2Al4B3diZ1wSWr59daXuhAIg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, go to the personal access tokens tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ATxbSj2cOh5seKuOcRq1nsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ATxbSj2cOh5seKuOcRq1nsQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, you can click “Generate new token” and Github will walk you through the rest. Once you have generated the token, make sure you save it to the clipboard, since we will need it for later.&lt;/p&gt;

&lt;p&gt;Now that we have generated our personal access token, we can work on the actual integration.&lt;/p&gt;
&lt;h2&gt;
  
  
  Service
&lt;/h2&gt;

&lt;p&gt;To start, let’s conceptualize how the portfolio would interact with the Github API.&lt;/p&gt;

&lt;p&gt;Building a separate service that communicates between the portfolio and the Github API is a good idea, since we should house our Github personal access token in a secure environment. &lt;/p&gt;

&lt;p&gt;Here is a depiction of the network flow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A46SCXZw_jnBqiDBZq_LbRQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2A46SCXZw_jnBqiDBZq_LbRQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start building out the service. &lt;/p&gt;

&lt;p&gt;I will be using Python and &lt;a href="https://flask.palletsprojects.com/en/1.1.x/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt;, but just understand that you can use any stack of your choice. &lt;/p&gt;

&lt;p&gt;First, let’s create a &lt;code&gt;config.py&lt;/code&gt; file. In this file, we will store our Github username and our personal access token. Make sure you do not push this file to version control.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR GITHUB USERNAME&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR PERSONAL ACCESS TOKEN FROM EARLIER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s create a &lt;code&gt;server.py&lt;/code&gt; file and make a simple Flask app.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_cors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CORS&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nc"&gt;CORS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    
       &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, let’s expose an endpoint that our portfolio can call to get the project data.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/projects&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;getProjects&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
       &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;getProjects()&lt;/code&gt; method will do three things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It will make a request to the Github API for the repository data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will extract the relevant fields from each of the repositories.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will return the filtered data back to the portfolio.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s tackle these steps one by one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Making a request to Github&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can simply use the Python requests library to make the HTTP request.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.github.com/users/USERNAME/repos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;        
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/vnd.github.mercy-preview+json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;        

    &lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USERNAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The Github API will also include the &lt;code&gt;topics&lt;/code&gt; field for each of the repositories if we pass in the above headers. &lt;/p&gt;

&lt;p&gt;If all goes correctly, the request should have a status of 200 and the &lt;code&gt;repos&lt;/code&gt; variable should be a list of json objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extracting relevant fields&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main fields of concern are &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;html_url&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;topics&lt;/code&gt;, and &lt;code&gt;homepage&lt;/code&gt;. The &lt;code&gt;homepage&lt;/code&gt; field represents the text stored in the black outlined area:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2438%2F1%2AWZNac2V96NI4CLprgWPUKA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2438%2F1%2AWZNac2V96NI4CLprgWPUKA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can put links to our demo gifs in &lt;code&gt;homepage&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The code to parse each of the repositories is this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;homepage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;topics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;topics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;images&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;homepage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Just to clarify, I added more than one demo link for certain projects. I separated each link with a semi-colon.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here is what &lt;code&gt;project&lt;/code&gt; would look like for the Path Finding Visualizer repository:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;206887035&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Pathfinding-Visualizer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/Ramko9999/Pathfinding-Visualizer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Built a colorful visualizer for shortest path algorithms: A star search, Breadth First Search, and Bidirectional Breadth First Search. Utilized Queues and Priority Queues to reduce collection operations such as pop() and push() to O(1) and O(log(n)) run times.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;topics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data-structures&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;graph-algorithms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;java&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pathfinding&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;swing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;images&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://media.giphy.com/media/U6GuVGBOQoHUHaZ7LV/giphy.gif&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://media.giphy.com/media/gg9eCb2ZBqcU4LlSML/giphy.gif&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://media.giphy.com/media/l4Wyj6PQwwxZdPjfSe/giphy.gif&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://media.giphy.com/media/LRgBCMGhCvqkzHzeaY/giphy.gif&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All that remains now is to return &lt;code&gt;projects&lt;/code&gt; back to the initiator of the request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Returning a response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can return the filtered data back to the client with the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    return {"projects": projects, "error": False}

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

&lt;/div&gt;


&lt;p&gt;So with all the pieces put together, the &lt;code&gt;getProjects()&lt;/code&gt; method will look as such:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Please be sure to test your service locally by calling the &lt;code&gt;/projects&lt;/code&gt; endpoint. Once it is working, you can deploy it wherever you like. Personally, I deployed the service on &lt;a href="https://www.pythonanywhere.com" rel="noopener noreferrer"&gt;pythonanywhere.com&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;Pat yourself on the back, as the hardest part is now over!&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrate
&lt;/h2&gt;

&lt;p&gt;All that remains now is that we have to make an HTTP request from our portfolio website to the service we have just created. &lt;/p&gt;

&lt;p&gt;For example, I used React to build out my portfolio, so here is how I made the call and fetched the projects.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;All you need to do now is to build out the user interface based on the data.&lt;/p&gt;

&lt;p&gt;With that said, feel free to head over to my &lt;a href="https://ramki-pitch.web.app/" rel="noopener noreferrer"&gt;portfolio&lt;/a&gt; to check out how I implemented my user interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's it folks!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>github</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>Client-Side Image Compression on the Web</title>
      <dc:creator>Ramki Pitchala</dc:creator>
      <pubDate>Wed, 21 Apr 2021 18:29:30 +0000</pubDate>
      <link>https://forem.com/ramko9999/client-side-image-compression-on-the-web-26j7</link>
      <guid>https://forem.com/ramko9999/client-side-image-compression-on-the-web-26j7</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/swlh/boost-server-performance-with-client-side-image-compression-cdefba1c1c0d" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;. If you prefer reading it from there, please do check it out.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Huge shoutout to &lt;a href="https://www.youtube.com/watch?v=bXf_UdyDzSA" rel="noopener noreferrer"&gt;Codú Community&lt;/a&gt; for inspiring this blog. All the code for this project is linked on &lt;a href="https://github.com/Ramko9999/Medium-Image-Compression-Client-Side" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;There are multiple ways of optimizing server performance. &lt;/p&gt;

&lt;p&gt;One way is to make the client do some of the work. &lt;/p&gt;

&lt;p&gt;Consider uploading images for profile pictures. Since high-quality images take up several MB, it is costly to send them over the network to the server. Also, since profile pictures don’t need to be extremely detailed, it would be nice to compress them and save space. &lt;/p&gt;

&lt;p&gt;Thankfully, with HTML Canvas, we can compress our images on the client itself. After the compression, we can then send the images to the server, reducing upload time and the work the server must do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setup demo HTML page&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listen to the image input&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resize and compress image with HTML Canvas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Demo of the compression working&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup demo HTML page
&lt;/h2&gt;

&lt;p&gt;To follow along, create a new project with the following files:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- index.html
- main.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;We will create the basic UI in &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Put the following in &lt;code&gt;index.html&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In addition to accepting file uploads, we will preview both the initial image the user uploads and our compressed version in the UI.&lt;/p&gt;

&lt;p&gt;Let’s go to &lt;code&gt;main.js&lt;/code&gt; to handle when a user inputs an image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Listen to the image input
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;main.js&lt;/code&gt;, let’s first define &lt;code&gt;getImageDimensions&lt;/code&gt;, which returns a Promise of an input image’s width and height. We need the initial image’s dimensions to maintain the aspect ratio when we resize.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getImageDimensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s now add an event listener to handle when our input tag, &lt;code&gt;image-input&lt;/code&gt;, changes.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The above listener will trigger whenever a user uploads an image. We take the uploaded image, display it to the user, and acquire its dimensions. All that is left is to resize and compress the image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resize and compress image with HTML Canvas
&lt;/h2&gt;

&lt;p&gt;Let’s get to the fun part and make the &lt;code&gt;compressImage&lt;/code&gt; function in &lt;code&gt;main.js&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;This is the magic!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given an HTML image, the scale factor, and the initial width and height of the image, the function creates an HTML Canvas and draws the image downscaled on it. &lt;/p&gt;

&lt;p&gt;Finally, we turn the downscaled image into a blob and resolve it from the Promise. The resolved blob represents our compressed image. &lt;/p&gt;

&lt;p&gt;We can now use this function to compress whatever image we want.&lt;/p&gt;

&lt;p&gt;Let’s integrate this into the event listener we created earlier.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s break this down.&lt;/p&gt;

&lt;p&gt;First, we create two compressed images with differing scales: the ratio of &lt;code&gt;MAX_WIDTH&lt;/code&gt; and the initial image’s width and the ratio of &lt;code&gt;MAX_HEIGHT&lt;/code&gt; and the initial image’s height (You can parameterize &lt;code&gt;MAX_WIDTH&lt;/code&gt; and &lt;code&gt;MAX_HEIGHT&lt;/code&gt; based on the use case).&lt;/p&gt;

&lt;p&gt;Then, we pick the smaller blob out of the two to be our compressed output and display it to the user. Finally, we check if our compressed version is smaller than the initial image. If the initial image was smaller, we can use it instead.&lt;/p&gt;

&lt;p&gt;We now can compress images whenever the user inputs an image on the client. &lt;code&gt;optimalBlob&lt;/code&gt; represents the image with the smallest size among both the compressed versions and the initial image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo of the compression working
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A7Zyw0voQ2rRuPgQ1" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A7Zyw0voQ2rRuPgQ1" alt="Photo by [Joshua Earle](https://unsplash.com/@joshuaearle) on [Unsplash](https://unsplash.com/photos/-87JyMb9ZfU)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I took the above image and submitted it into our file input.&lt;/p&gt;

&lt;p&gt;Here is what occurred:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/QHJS7WRmL0vYTrgUUv/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/QHJS7WRmL0vYTrgUUv/giphy.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the compressed result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ArYgb4t-aEgmjfd36MqG9EA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F1%2ArYgb4t-aEgmjfd36MqG9EA.png" alt="Compressed Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The initial size of the image was roughly 299 KB and the compressed result was only 45 KB, a huge reduction. &lt;/p&gt;

&lt;p&gt;With this reduction in size, it will be much faster to send the image to the server, and the server doesn’t need to worry about compressing it either. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is a win-win situation!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However, if image quality is important, this approach is not a good idea, since resizing through HTML Canvas is lossy.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Despite that, this is a great way to handle the uploads of profile pictures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s all I got. Thanks for reading!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>html</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Host and Use Redis for Free</title>
      <dc:creator>Ramki Pitchala</dc:creator>
      <pubDate>Wed, 21 Apr 2021 01:22:31 +0000</pubDate>
      <link>https://forem.com/ramko9999/host-and-use-redis-for-free-51if</link>
      <guid>https://forem.com/ramko9999/host-and-use-redis-for-free-51if</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/swlh/host-and-use-redis-for-free-b70d65a13edd" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;. If you prefer reading it from there, please do check it out.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Although building software projects can be challenging, deployment can be a pain. &lt;/p&gt;

&lt;p&gt;In fact, in situations where speed is necessary, deployment must be seamless. For that reason, I want to show you how to deploy Redis for free and use Redis remotely. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://redislabs.com/" rel="noopener noreferrer"&gt;Redis Labs&lt;/a&gt;, a Redis cloud hosting service, offers a free plan with simple deployment steps. We will leverage that plan to create an instance and integrate that instance with Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Walk Through
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Do everything quickly and well.&lt;br&gt;
― G.I. Gurdjieff&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To start, head over to &lt;a href="https://redislabs.com/" rel="noopener noreferrer"&gt;https://redislabs.com/&lt;/a&gt; and sign up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AwErfShGOjlbPVbnTmvDCrA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AwErfShGOjlbPVbnTmvDCrA.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you create and verify your account, you will end up on this screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2A8tEXz40I048vjI9P0WXuBA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2A8tEXz40I048vjI9P0WXuBA.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “Create your subscription”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3804%2F1%2A9s4XRGY6NGnvH-Dcmn_z9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3804%2F1%2A9s4XRGY6NGnvH-Dcmn_z9w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to “Fixed size” and pick the free option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3798%2F1%2AZJae6g3-D98R0n7cZ8lS0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3798%2F1%2AZJae6g3-D98R0n7cZ8lS0g.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “Create”. We now need to create our database under the subscription.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3810%2F1%2AMiFD4JsIghT7Q0ZWI_KSVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3810%2F1%2AMiFD4JsIghT7Q0ZWI_KSVA.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter in the database name. Be sure to copy “Redis Password”. Once you are ready, click “Activate”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AujM1mWiIt2UuHuTuzxg2dA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3796%2F1%2AujM1mWiIt2UuHuTuzxg2dA.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use the endpoint to connect to our remote instance so be sure to copy it down. For security reasons, be careful with who you expose your endpoint to.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;It is really that quick!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration
&lt;/h2&gt;

&lt;p&gt;Let’s connect to our remote Redis instance! Although I will use Node.js, the connection process will most likely be similar to the other technologies.&lt;/p&gt;

&lt;p&gt;Start by creating a new npm project.&lt;/p&gt;

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

&lt;/div&gt;
&lt;p&gt;After filling out the project details, cd into your project and install &lt;a href="https://redis.js.org/" rel="noopener noreferrer"&gt;redis&lt;/a&gt;, a Node.js client for Redis, and &lt;a href="https://www.npmjs.com/package/dotenv" rel="noopener noreferrer"&gt;dotenv&lt;/a&gt;, an environment variable loader.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install redis

npm install dotenv --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In the root directory, create a file called &lt;code&gt;.env&lt;/code&gt; . In it, let’s put our Redis instance hostname, port, and password.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We can find the hostname, port, and password in the View Database section:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2636%2F1%2AynXHj7nEJLLnEOxXq7OSrg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2636%2F1%2AynXHj7nEJLLnEOxXq7OSrg.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contents of &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

    &lt;span class="nx"&gt;REDIS_HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;YOUR&lt;/span&gt; &lt;span class="nx"&gt;REDIS&lt;/span&gt; &lt;span class="nx"&gt;HOSTNAME&lt;/span&gt;
    &lt;span class="nx"&gt;REDIS_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;YOUR&lt;/span&gt; &lt;span class="nx"&gt;REDIS&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt;
    &lt;span class="nx"&gt;REDIS_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;YOUR&lt;/span&gt; &lt;span class="nx"&gt;REDIS&lt;/span&gt; &lt;span class="nx"&gt;PASSWORD&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Create &lt;code&gt;index.js&lt;/code&gt;. Let’s say this is where we want to connect to our remote instance. Let’s create a client and test if we can connect to it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now we can connect to our Redis instance from Node.js!&lt;/strong&gt;&lt;/p&gt;



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

&lt;p&gt;I wanted to show a simple way to deploy and use Redis for free, whether it be for demoing a project at a hackathon or evaluating a proof of concept idea.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thank you for taking the time to read this blog!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>redis</category>
      <category>node</category>
    </item>
    <item>
      <title>Set a Time Limit on Async Actions</title>
      <dc:creator>Ramki Pitchala</dc:creator>
      <pubDate>Mon, 19 Apr 2021 17:01:56 +0000</pubDate>
      <link>https://forem.com/ramko9999/set-a-time-limit-on-async-actions-452b</link>
      <guid>https://forem.com/ramko9999/set-a-time-limit-on-async-actions-452b</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/swlh/boost-server-performance-with-client-side-image-compression-cdefba1c1c0d"&gt;Medium&lt;/a&gt;. If you prefer reading it from there, please do check it out.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Asynchronous programming is incredible! &lt;/p&gt;

&lt;p&gt;With it, we can run our IO-intensive tasks without having to block the execution of other code. &lt;/p&gt;

&lt;p&gt;However, in situations where the code after a blocking task depends on the task’s result, we must wait. Now, imagine if the blocking task took a long time to finish or it never finished. This could be problematic in the context of the application. &lt;/p&gt;

&lt;p&gt;We can solve this issue by setting a time limit on our task. If our task doesn’t finish in the span of the time limit, we can return a failure value instead. Let me elaborate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;Let’s suppose that the blocking task is a promise called &lt;code&gt;longTask&lt;/code&gt;, and it was used in the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
       &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;longTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="nx"&gt;doSomethingImportantWithData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the time it takes &lt;code&gt;longTask&lt;/code&gt; to settle is longer than our requirements or if &lt;code&gt;longTask&lt;/code&gt; is never settled, we won’t be able to execute the code after &lt;code&gt;longTask&lt;/code&gt; in a timely manner.&lt;/p&gt;

&lt;p&gt;However, imagine if we could set a time limit on our blocking tasks. In the case that the blocking task doesn’t settle within the time limit, we can return a failure value from the task. In the scenario the task resolves, we can return the value it resolved to.&lt;/p&gt;

&lt;p&gt;To elaborate, suppose there was a function called &lt;code&gt;fulfillWithTimeLimit&lt;/code&gt; which takes in milliseconds, the time limit, task, the task promise we would like to set a time limit on, and &lt;code&gt;failureValue&lt;/code&gt;, the value that would be resolved from &lt;code&gt;fulfillWithTimeLimit&lt;/code&gt; if &lt;code&gt;task&lt;/code&gt; never completes within the time limit.&lt;/p&gt;

&lt;p&gt;In the case that &lt;code&gt;longTask&lt;/code&gt; is resolved before the time limit, &lt;code&gt;fulfillWithTimeLimit&lt;/code&gt; returns with the value resolved from &lt;code&gt;longTask&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In the case that &lt;code&gt;longTask&lt;/code&gt; never finishes within the span of the time limit, the function should immediately return &lt;code&gt;failureValue&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;With this approach, we ensure that we never have to wait on &lt;code&gt;longTask&lt;/code&gt; for more than the specified time limit.&lt;/p&gt;

&lt;p&gt;Let’s dig into the approach.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;In order to “set a time limit” on the task, we can create another promise, &lt;code&gt;timeoutPromise&lt;/code&gt;, which resolves to &lt;code&gt;failureValue&lt;/code&gt; after the time limit. After that, we can race both our &lt;code&gt;timeoutPromise&lt;/code&gt; and task with &lt;a href="https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise/race"&gt;&lt;code&gt;Promise.race&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.race&lt;/code&gt; takes in a list of promises and resolves or rejects to the value of the promise in the list that is settled first.&lt;/p&gt;

&lt;p&gt;To provide an example, suppose I had the two following promises:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A finished before!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B finished!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Suppose I raced these promises and got the value.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finishString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Since a resolves after 100 milliseconds while &lt;code&gt;b&lt;/code&gt; resolves after 1000 milliseconds, &lt;code&gt;a&lt;/code&gt; will be the first promise to resolve. As a result, &lt;code&gt;finishString&lt;/code&gt; will be equal to “A finished before!”. If you would like to learn more about &lt;code&gt;Promise.race&lt;/code&gt;, please check out the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race"&gt;&lt;strong&gt;Promise.race()&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nonetheless, let’s apply the promise racing idea to create the &lt;code&gt;fulfillWithTimeLimit&lt;/code&gt; function.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;To begin, we create our &lt;code&gt;timeoutPromise&lt;/code&gt; and ensure it resolves with the &lt;code&gt;failureValue&lt;/code&gt; after the time limit. Then, we race to see whether our task or &lt;code&gt;timeoutPromise&lt;/code&gt; finishes first. For safety, we can clear the timeout and return &lt;code&gt;response&lt;/code&gt;, the resolved value of the race.&lt;/p&gt;

&lt;p&gt;Here is how &lt;code&gt;doSomething&lt;/code&gt; looks now:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the above example, I set &lt;code&gt;failureValue&lt;/code&gt; to null. However, it may be better to set it to a value of the same type as what is resolved from the task. In fact, it may be better to call reject in the &lt;code&gt;timeoutPromise&lt;/code&gt; than to resolve with a &lt;code&gt;failureValue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s it!&lt;/strong&gt; We can easily reuse &lt;code&gt;fulfillWithTimeLimit&lt;/code&gt; in our application code where we need a time limit.&lt;/p&gt;

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

&lt;p&gt;In this blog, I aimed to show a solution with &lt;code&gt;Promise.race&lt;/code&gt; to handle situations where blocking tasks may fail to settle or take too long to settle. Though I did not cover all the functionalities of promises, I hope this article amplifies your curiosity to explore them more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"&gt;&lt;strong&gt;Promise&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race"&gt;&lt;strong&gt;Promise.race()&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tutorialspoint.com/what-is-settimeout-method-in-javascript"&gt;&lt;strong&gt;setTimeout&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>node</category>
    </item>
    <item>
      <title>Crunch Pokemon Data with Python and Deta Base</title>
      <dc:creator>Ramki Pitchala</dc:creator>
      <pubDate>Sun, 18 Apr 2021 21:09:50 +0000</pubDate>
      <link>https://forem.com/ramko9999/crunch-pokemon-data-with-python-and-deta-base-2p</link>
      <guid>https://forem.com/ramko9999/crunch-pokemon-data-with-python-and-deta-base-2p</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://python.plainenglish.io/crunch-pokemon-data-with-deta-base-bd9c97d96ad3" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;. If you prefer reading it from there, please do check it out.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Performance is a must when it comes to building software. However, in certain situations, the speed to set up and integrate new services for proof of concept evaluation or infrastructure is overlooked. Specifically, in the realm of databases, there are many options, but I find &lt;a href="https://www.deta.sh/" rel="noopener noreferrer"&gt;Deta&lt;/a&gt; to be most seamless to set up and use. Deta offers Deta Base (I will refer to it as Base), a NoSQL data store optimized for developer simplicity. In this article, I aim to show how to set up a Deta project and interact with your Base to store and manipulate Pokemon data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/139JVKQ8m6GeuQ/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/139JVKQ8m6GeuQ/giphy.gif" alt="Team Rocket"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s get started!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CRUD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Querying&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;To begin, navigate to &lt;a href="https://web.deta.sh/" rel="noopener noreferrer"&gt;Sign Up&lt;/a&gt;, create a new account, and verify your account. Once you sign in, you should be on the following page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3828%2F1%2ATgHKkBFeHYKwAqqRvEuaXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3828%2F1%2ATgHKkBFeHYKwAqqRvEuaXg.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the arrow in the top left, we will create a new project from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2AO1mNYmNDwpWs8PAHjxTN1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3840%2F1%2AO1mNYmNDwpWs8PAHjxTN1w.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter a name of your choice and hit create! A popup with your project key and project id will appear. Make sure you save the key!&lt;/p&gt;

&lt;p&gt;With the project key saved, create a new directory, walk into it and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install flask deta&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flask.palletsprojects.com/en/1.1.x/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt; is a web framework that we will use to create endpoints to listen to incoming requests. Based on the requests, we will interact with our remote database using the deta package.&lt;/p&gt;

&lt;p&gt;Here is how the folder structure will look like:&lt;/p&gt;

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

config.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In &lt;code&gt;config.py&lt;/code&gt;, we will store our project key&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DETA_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_COPIED_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In our project, we will create a Base called pokemon and utilize it to store, access, and manipulate Pokemon data. Before that, let’s go over the schema for a record in pokemon:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Each record in a Base must correspond to a unique identifier called key. When we insert a Pokemon record into our Base, we will provide name as our key. As a result, if we needed to get information on Charizard, we just have to ask pokemon to find the associated record with Charizard as its key.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;app.py&lt;/code&gt;, let’s set up the Flask app and our connection to our Base, pokemon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DETA_KEY&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;deta&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Deta&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;json.decoder&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;JSONDecoder&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;deta_project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Deta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DETA_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deta_project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pokemon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONDecoder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All the data access and manipulations will occur through &lt;code&gt;db&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our setup is now complete! Onto the CRUD!&lt;/p&gt;
&lt;h2&gt;
  
  
  CRUD
&lt;/h2&gt;

&lt;p&gt;CRUD is an acronym for creating, reading, updating, and deleting data in a database. We will explore how to perform each of the above operations in our pokemon Base. All the work will be done in &lt;code&gt;app.py&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Insertion
&lt;/h3&gt;

&lt;p&gt;Deta provides 2 ways of inserting data. The first is through the &lt;a href="https://docs.deta.sh/docs/base/sdk#put" rel="noopener noreferrer"&gt;&lt;code&gt;put&lt;/code&gt;&lt;/a&gt; method. &lt;code&gt;put&lt;/code&gt; is the faster method of insertion. If you call &lt;code&gt;put&lt;/code&gt; on a record that already exists in the base, &lt;code&gt;put&lt;/code&gt; will overwrite the record. In contrast, &lt;a href="https://docs.deta.sh/docs/base/sdk#put" rel="noopener noreferrer"&gt;&lt;code&gt;insert&lt;/code&gt;&lt;/a&gt; is 2x slower than &lt;code&gt;put&lt;/code&gt;. In the case that you try to insert into the Base with an already existing key, it will throw an error.&lt;/p&gt;

&lt;p&gt;Let’s create an endpoint to insert a new Pokemon with &lt;code&gt;put&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Here is what the endpoint would look like using &lt;code&gt;insert&lt;/code&gt; :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Deta also supports inserting multiple records at the same time with put_many. According to the documentation, it is possible to insert at most 25 items into the Base in a single call (&lt;a href="https://docs.deta.sh/docs/base/sdk#put-many" rel="noopener noreferrer"&gt;Deta Base SDK&lt;/a&gt;).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s test out what we have so far. Let’s insert the data for Pichu into the Base via an HTTP POST through &lt;code&gt;/pokemon&lt;/code&gt; on Postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2688%2F1%2AjXuk1uvzHgw_Oc54okwsqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2688%2F1%2AjXuk1uvzHgw_Oc54okwsqg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you hit send, navigate back to &lt;a href="https://web.deta.sh/home/Ramko9999/default" rel="noopener noreferrer"&gt;Deta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3822%2F1%2AkelCdjWliRDu4ORQ2KUJSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3822%2F1%2AkelCdjWliRDu4ORQ2KUJSw.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on your Base under the &lt;strong&gt;Bases&lt;/strong&gt; section. You will now be able to view the data in your Base.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2988%2F1%2AsaJ77wMEGlkTT5rq2vl_fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2988%2F1%2AsaJ77wMEGlkTT5rq2vl_fw.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, Pichu is in our pokemon Base!&lt;/p&gt;

&lt;h3&gt;
  
  
  Access
&lt;/h3&gt;

&lt;p&gt;We can use the &lt;a href="https://docs.deta.sh/docs/base/sdk/#get" rel="noopener noreferrer"&gt;&lt;code&gt;get&lt;/code&gt;&lt;/a&gt; method to access the record of a given key.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since our Pokemon name is the key, we can directly access its record by providing its name. We can test it with the following GET request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2686%2F1%2A97_qFgHmoKagFg7Dtknp0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2686%2F1%2A97_qFgHmoKagFg7Dtknp0w.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Updation
&lt;/h3&gt;

&lt;p&gt;As stated previously in &lt;strong&gt;Insertion&lt;/strong&gt;, the &lt;code&gt;put&lt;/code&gt; function can be used for overwriting records. However, &lt;code&gt;put&lt;/code&gt; completely overwrites the record and can remove prior fields that are not part of the new updates. As result, if we want to partially update the record, we can use the &lt;a href="https://docs.deta.sh/docs/base/sdk#update" rel="noopener noreferrer"&gt;&lt;code&gt;update&lt;/code&gt;&lt;/a&gt; function. In fact, &lt;code&gt;update&lt;/code&gt; also allows for fine-grained updations like incrementing values and appending, prepending, and removing elements in a list (&lt;a href="https://docs.deta.sh/docs/base/sdk#update" rel="noopener noreferrer"&gt;Deta Base SDK&lt;/a&gt;).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s make sure updating works with an example. First, I will insert the following data for Charizard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Johto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Charizard is from Kanto region
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charizard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;height&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weight&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;90.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fire&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# Charizard also Flying type
&lt;/span&gt;        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evolution&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;region&lt;/code&gt; should be Kanto, and Charizard is also a flying type. Let’s update Charizard with a POST request to &lt;code&gt;/pokemon/update/Charizard&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2682%2F1%2A2Os_Wp85latc_fOM2FQ0Lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2682%2F1%2A2Os_Wp85latc_fOM2FQ0Lg.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a GET request to &lt;code&gt;/pokemon/Charizard&lt;/code&gt;, it is clear that &lt;code&gt;region&lt;/code&gt; and &lt;code&gt;type&lt;/code&gt; are updated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2710%2F1%2Amm-besOPWb3zpVmVk2NjhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2710%2F1%2Amm-besOPWb3zpVmVk2NjhA.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Deletion
&lt;/h3&gt;

&lt;p&gt;Deta provides &lt;a href="https://docs.deta.sh/docs/base/sdk#delete" rel="noopener noreferrer"&gt;&lt;code&gt;delete&lt;/code&gt;&lt;/a&gt;, a function that takes in a key and deletes the record associated with the key.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;If I wanted to delete Charizard, I would make an HTTP DELETE request to &lt;code&gt;/pokemon/delete/Charizard&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have now explored how to insert, access, update and delete from our Base. Let’s learn how to query our Base.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying
&lt;/h2&gt;

&lt;p&gt;Prior to querying, make sure to fill up your Base with some more Pokemon.&lt;/p&gt;

&lt;p&gt;Querying is done through the &lt;a href="https://docs.deta.sh/docs/base/sdk#fetch" rel="noopener noreferrer"&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/a&gt; method. To elaborate, fetch takes in a &lt;a href="https://docs.deta.sh/docs/base/sdk/#queries" rel="noopener noreferrer"&gt;query&lt;/a&gt; or a list of queries and accumulates a list of records whose fields match the query or queries.&lt;/p&gt;

&lt;p&gt;A query is nothing more than a dictionary where the mapping between the keys and values represents the query condition. For instance, suppose I wanted to get Blastoise’s record with a query instead of &lt;code&gt;get&lt;/code&gt;, here is how it would work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Blastoise&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;blastoise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We accumulate all the records with &lt;code&gt;name&lt;/code&gt; equal to Blastoise.&lt;/p&gt;

&lt;p&gt;It is also possible to query based on inequalities. For instance, we can query for all Pokemon that weigh greater than 100kg and are less than 1 meter tall.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weight?gt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;height?lt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;pokemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can append “?gt” and “?lt” at the end of numerical fields to query for records with respective values greater than or less than a threshold. There are a lot more suffixes that can be added to the end of a query field, so I recommend reading the documentation for your specific use case (&lt;a href="https://docs.deta.sh/docs/base/sdk/#queries" rel="noopener noreferrer"&gt;Deta Base SDK&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Let’s create an endpoint that will return Pokemon which are of a parameter type.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;“?contains” checks if a provided query element exists in the list associated with the field. To provide an example, if I wanted all the fire-type Pokemon, I would send a GET request to &lt;code&gt;/pokemon/type/Fire&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FMO2GmcG.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FMO2GmcG.gif" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are 13 Pokemon returned from the above request.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is a little overwhelming since this query will return all the fire-type Pokemon in our Base. Deta also provides us with the ability to limit the number of query results with &lt;a href="https://docs.deta.sh/docs/base/sdk/#example-using-buffer-pages-1" rel="noopener noreferrer"&gt;buffer&lt;/a&gt;. Let’s set the buffer arg in fetch to 2.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now, we only get two records back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2692%2F1%2AZ-BgZLjSFIdWVceL8tqY-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2692%2F1%2AZ-BgZLjSFIdWVceL8tqY-Q.png" alt="Photo by Author"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, by changing the &lt;code&gt;pages&lt;/code&gt; argument in &lt;code&gt;fetch&lt;/code&gt;, it is possible to spread the result data over multiple pages.&lt;/p&gt;

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

&lt;p&gt;My primary goal with this writing was to shed greater light on a database that you can set up and work on in the blink of an eye. It took hardly much time to create the project and based on the above examples, CRUD and Querying are as simple as they can get. For these reasons, Deta Base is perfect for proof of concepts, serverless applications, hackathons, and many more situations and projects that require simplicity and speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.deta.sh/" rel="noopener noreferrer"&gt;&lt;strong&gt;Deta (Home)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flask.palletsprojects.com/en/1.1.x/" rel="noopener noreferrer"&gt;&lt;strong&gt;Flask&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.deta.sh/docs/base/sdk" rel="noopener noreferrer"&gt;&lt;strong&gt;Deta SDK&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bulbapedia.bulbagarden.net/wiki/Main_Page" rel="noopener noreferrer"&gt;&lt;strong&gt;Bulbapedia&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>database</category>
      <category>python</category>
    </item>
  </channel>
</rss>
