<?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: Daniel Schep</title>
    <description>The latest articles on Forem by Daniel Schep (@dschep).</description>
    <link>https://forem.com/dschep</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%2F21410%2F59ee161a-41bc-42c2-8725-eebcc1813c59.jpg</url>
      <title>Forem: Daniel Schep</title>
      <link>https://forem.com/dschep</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dschep"/>
    <language>en</language>
    <item>
      <title>Creating an IG top 9 without using creepy 3rd party apps</title>
      <dc:creator>Daniel Schep</dc:creator>
      <pubDate>Tue, 31 Dec 2019 14:48:25 +0000</pubDate>
      <link>https://forem.com/dschep/creating-an-ig-top-9-without-using-creepy-3rd-party-apps-4ga8</link>
      <guid>https://forem.com/dschep/creating-an-ig-top-9-without-using-creepy-3rd-party-apps-4ga8</guid>
      <description>&lt;p&gt;It's that time of year again when everyone on Instagram is posting their #top9. I wanted one too, but I don't trust whatever app people are authenticating with their Instagram accounts because it shares more with a 3rd party than I care to do. (TL;DR: use the script in &lt;a href="https://gist.github.com/dschep/28bf9848d76d4790df1330a246cc90cc"&gt;this gist&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Fortunately, a quick googling led me to the &lt;a href="https://github.com/realsirjoe/instagram-scraper"&gt;&lt;code&gt;igramscraper&lt;/code&gt; python library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then the first step was using it's &lt;code&gt;get_medias&lt;/code&gt; function:&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;instagram&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_medias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_schep"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# use your account of course!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we need to filter to only this year's photos and sort by likes and grab the top 9. For this we use the standard library &lt;code&gt;datetime&lt;/code&gt; module, a list comprehension, &lt;code&gt;sorted&lt;/code&gt; and a slice to limit the result to 9.&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;this_year_photos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;created_time&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt;
    &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TYPE_IMAGE&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;top9&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_year_photos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;likes_count&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we have a list of your top 9 most liked photos of 2019! Next we need to download them and create your top9 image. For this we use the popular &lt;a href="https://2.python-requests.org"&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://python-pillow.org/"&gt;&lt;code&gt;Pillow&lt;/code&gt;&lt;/a&gt; libraries:&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;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RGB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1080&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# create the new image
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;top9&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# download and open the image
&lt;/span&gt;    &lt;span class="n"&gt;tile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image_high_resolution_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# resize the image
&lt;/span&gt;    &lt;span class="n"&gt;tile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ANTIALIAS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# paste it into our new image
&lt;/span&gt;    &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The call to &lt;code&gt;img.paste&lt;/code&gt; is a little bit obtuse. I'm using the modulo(&lt;code&gt;%&lt;/code&gt;) operator to determine what column the image is on then multiplying by the size of the image and using the floor division(&lt;code&gt;//&lt;/code&gt;) operator to determine the row.&lt;/p&gt;

&lt;p&gt;Then we save it!&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;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-top9.jpg"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you have non-square images in your top 9, you might notice that they are deformed. To deal with this, we crop our tile before resizing it:&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;tile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crop&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="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&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;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;tile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crop&lt;/span&gt;&lt;span class="p"&gt;(&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;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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;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;🎉 We've just created our own top9 image with out having to authenticate our account with a creep 3rd party IG app!&lt;/p&gt;

&lt;p&gt;Check out the full source code for an easy to use version of this script in this Gist:  &lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



</description>
      <category>instagram</category>
      <category>top9</category>
      <category>python</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How To Host a React App on AWS using Amazon S3 and CloudFront</title>
      <dc:creator>Daniel Schep</dc:creator>
      <pubDate>Tue, 13 Aug 2019 14:14:15 +0000</pubDate>
      <link>https://forem.com/dschep/how-to-host-a-react-app-on-aws-using-amazon-s3-and-cloudfront-bgo</link>
      <guid>https://forem.com/dschep/how-to-host-a-react-app-on-aws-using-amazon-s3-and-cloudfront-bgo</guid>
      <description>&lt;p&gt;Here's a tutorial on how you can deploy React applications that are fast, global and cheap to host.&lt;/p&gt;

&lt;p&gt;The outcome of this is a website with a React app, a custom domain and SSL certificate — &lt;strong&gt;Basically, everything you need to be production ready.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And all of this will be made simple via the Serverless Framework and its new Serverless Components feature.&lt;/p&gt;

&lt;p&gt;This post features few images because an entire walkthrough video of this tutorial can be found here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ts26BVuX3j0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Your React app will be distributed via a global Content Delivery Network.  This enables it to have incredibly fast performance around the world.&lt;/p&gt;

&lt;p&gt;And we will be using possibly the cheapest infrastructure to do this which is S3 and Cloudfront from Amazon Web Services.&lt;/p&gt;

&lt;p&gt;How cheap is that?  &lt;/p&gt;

&lt;p&gt;For a year, you can transfer 50 GB of data and serve 2 million requests a month, &lt;strong&gt;for free&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;After that, it will cost you 8-2 cents per GB, depending on how much data you transfer, plus 1 cent per 10,000 HTTPs requests.  Check out the AWS Cloudfront pricing page for more details.&lt;/p&gt;

&lt;p&gt;You will have to pay for your custom domain.  However, you will get a free public SSL certificate from AWS Certificate Manager.&lt;/p&gt;

&lt;p&gt;Now a disclaimer – I did not analyze all of the options on the market for static site hosting before this, so I'm not aware of cheaper alternatives that may exist.  But, S3 and Cloudfront have been around for many years.  They're reliable and fast.  Actually, many products for static site hosting are built on S3 and Cloudfront and charge you a mark-up.&lt;/p&gt;

&lt;p&gt;The reason why developers don't often use plain AWS S3 and AWS Cloudfront is because the experience of using them is just too darn complicated, compared to other offerings.&lt;/p&gt;

&lt;p&gt;However, this is where Serverless Framework comes in.  It brings a great developer experience to all infrastructure providers, especially infrastructure with auto-scaling, pay-per-use, AKA "serverless" qualities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set-Up
&lt;/h3&gt;

&lt;p&gt;Before doing anything, you will need to have an AWS account.  You must have a credit card to sign up, though you will not be charged until you go over the free tier limits.&lt;/p&gt;

&lt;p&gt;Next, log into AWS, navigate to the IAM dashboard to create access keys that the Serverless Framework will use to provision the infrastructure needed for your React website.&lt;/p&gt;

&lt;p&gt;Go to "Users", and click "add user".  Give it a name that includes serverless-framework then click enable "Programmatic Access", and click "Next".  &lt;/p&gt;

&lt;p&gt;Select "Attach existing policies directly".  Check the box next to "AdministratorAccess".  Hit "Next" and "Next" again to skip the tags screen, then hit "Create".&lt;/p&gt;

&lt;p&gt;Note:  Later, you may want to scope down these permissions so the Serverless Framework will the least amount of access necessary.  Though, this can be complex because the Serverless Framework uses many AWS services.  To give you a helping hand here, the Website Component currently uses S3, Certificate Manager, Cloudfront and Route53, and needs access specifically for those.&lt;/p&gt;

&lt;p&gt;Copy the "Access Key ID" and the "Secret Access Key".  You will need them in second... &lt;/p&gt;

&lt;p&gt;Now, it's time for the fun Serverless Framwork part.&lt;/p&gt;

&lt;p&gt;Make sure you have &lt;a href="https://nodejs.org/en/download/"&gt;Node.js&lt;/a&gt; installed.  Then, install the Serverless Framework via NPM and add the global flag &lt;code&gt;-g&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you have Serverless Framework version 1.49 or later installed.  Hint:  If you're installing it right now, you will.&lt;/p&gt;

&lt;p&gt;We're going to use a Website template that has all of the scaffolding you need to get started quickly.  It's a complete boilerplate.  Install the Website template using this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ serverless create --template-url https://github.com/serverless/components/tree/master/templates/website
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;website&lt;/code&gt; folder for you.&lt;/p&gt;

&lt;p&gt;Go into that folder and install the React dependencies via npm by running &lt;code&gt;npm i&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Also in the &lt;code&gt;website&lt;/code&gt; folder, create a file named &lt;code&gt;.env&lt;/code&gt; and paste in your AWS Keys, formatted like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS_ACCESS_KEY_ID=A92JA098J10FAJ10JAAFASF
AWS_SECRET_ACCESS_KEY=fJajajaf0919jIJFJA7813hAAFJHL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're done with set-up.  It's time to start development!&lt;/p&gt;

&lt;h3&gt;
  
  
  Development
&lt;/h3&gt;

&lt;p&gt;This project uses React and Parcel for building and bundling the application.&lt;/p&gt;

&lt;p&gt;You can also run the application locally with Parcel using this 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 run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can develop rapidly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;Out of the box, the Website template should be ready to deploy.&lt;/p&gt;

&lt;p&gt;If you look at your &lt;code&gt;serverless.yml&lt;/code&gt; file, you will see a Serverless Compont in it titled "website".  A Serverless Component is simply code that knows how to deploy the cloud infrastructure needed to create a specific outcome or use-case.&lt;/p&gt;

&lt;p&gt;Serverless Components are open-source and you can use them to easily deploy lots of use-cases on serverless cloud infrastructure.  &lt;a href="https://www.github.com/serverless/components"&gt;Check them out here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Every Serverless Component has an &lt;code&gt;inputs&lt;/code&gt; property, which allows you to configure the use-case that the Component will provision.  For example, here you can see the &lt;code&gt;src&lt;/code&gt; input that points to the directory containing your website assets.  As well as a &lt;code&gt;hook&lt;/code&gt; to call in order to build your website before deployment. This way, you don't have to run the build script before deploying, it just happens automatically.&lt;/p&gt;

&lt;p&gt;Alright, let's get to the deployment part!&lt;/p&gt;

&lt;p&gt;To deploy your React app, in your website folder, simply run the &lt;code&gt;serverless&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your website should deploy in less than a minute and you should get URL pointing to your live website!.  &lt;/p&gt;

&lt;p&gt;The first deployment always takes the longest because creating cloud infrastructure resources can be more time-consuming than updating them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up A Custom Domain, Cloudfront &amp;amp; SSL Certificate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To set up your custom domain, your Cloudfront CDN and an SSL certificate, you will need to do one manual step: you must log into your AWS account and purchase your domain.  Currently, the Website Component only works with domains purchased on AWS Route53.  Within the next few weeks, we will enable support for existing domains registered on different registrars.&lt;/p&gt;

&lt;p&gt;Go to AWS Route53's dashboard, egister your domain and wait for the registration to complete.  This could take up to an hour.  Once it has completed, simply add in the custom domain to the Website Component's inputs.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;serverless&lt;/code&gt; again and it will acknowledge the new &lt;code&gt;input&lt;/code&gt; and set up your custom domain, Cloudfront &amp;amp; SSL Certificate.&lt;/p&gt;

&lt;p&gt;You will need to wait for your new domain to propogate to the DNS servers around the world. This may take up to an hour as well. Once it's available, you will be able to see it live, as well as any changes you make.&lt;/p&gt;

&lt;p&gt;Every time you run &lt;code&gt;serverless&lt;/code&gt; to deploy changes to your website, the Website Component invalidates the assets you have cached in AWS Cloudfront. This enables you to see changes almost immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Management
&lt;/h3&gt;

&lt;p&gt;Currently, Serverless Components do not have remote state management.  This is coming within a month.  Until then, make sure you push the &lt;code&gt;.serverless&lt;/code&gt; directory to Github, since it contains state info about the cloud infrastructure resources that have been deployed for your website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding A Serverless API Backend, Database &amp;amp; More
&lt;/h3&gt;

&lt;p&gt;If you want to go further and build out a fullstack application just as easily as this website, check out &lt;a href="https://github.com/serverless/components/tree/master/templates/fullstack-application"&gt;the fullstack application template&lt;/a&gt;.  This will give you everything you need to deliver a fast, cheap and global entire serverless application.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>react</category>
      <category>cloudfront</category>
    </item>
    <item>
      <title>Introducing Proven</title>
      <dc:creator>Daniel Schep</dc:creator>
      <pubDate>Wed, 15 Nov 2017 21:41:57 +0000</pubDate>
      <link>https://forem.com/dschep/introducing-proven-9c4</link>
      <guid>https://forem.com/dschep/introducing-proven-9c4</guid>
      <description>&lt;p&gt;I'm pleased to introduce &lt;a href="https://github.com/dschep/proven" rel="noopener noreferrer"&gt;Proven&lt;/a&gt; to the &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; community. It is a browser extension for Firefox &amp;amp; Chrome to add badges to users' names on Twitter as an alternative to their verified program.&lt;/p&gt;

&lt;p&gt;Proven uses &lt;a href="https://keybase.io" rel="noopener noreferrer"&gt;Keybase&lt;/a&gt;'s API to look up a user by their twitter handle and if they have an account, it adds badges for their keybase profile as well as other profiles that have been linked by posting a proof.&lt;/p&gt;

&lt;p&gt;This is what it looks like in action! (all the badges are clickable links to the relevant profiles)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b7p76r2wjce52tu4nli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0b7p76r2wjce52tu4nli.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install it on &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/proven/" rel="noopener noreferrer"&gt;Firefox&lt;/a&gt; or &lt;a href="https://chrome.google.com/webstore/detail/proven/algligpkkhlodbalbiilbfiihcooekjn?hl=en-US&amp;amp;gl=US" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt;. And check out the source on &lt;a href="https://github.com/dschep/proven" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Now with night mode and mobile (&lt;a href="https://play.google.com/store/apps/details?id=org.mozilla.firefox" rel="noopener noreferrer"&gt;use the 🦊&lt;/a&gt;) support!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1co6pj6jdybzrzxgalty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1co6pj6jdybzrzxgalty.png" width="412" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; Now with tweetdeck support!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gbl3tjwb5pbodx4mfgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gbl3tjwb5pbodx4mfgj.png" width="800" height="920"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twitter</category>
      <category>showdev</category>
      <category>keybase</category>
      <category>crypto</category>
    </item>
  </channel>
</rss>
