<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chenglu</title>
    <description>The latest articles on DEV Community by Chenglu (@louisshe).</description>
    <link>https://dev.to/louisshe</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%2F324370%2F1a308a39-0833-4d5a-9ae2-6a78bf169e98.jpeg</url>
      <title>DEV Community: Chenglu</title>
      <link>https://dev.to/louisshe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/louisshe"/>
    <language>en</language>
    <item>
      <title>Installing Python 3.7.4 from source</title>
      <dc:creator>Chenglu</dc:creator>
      <pubDate>Sat, 22 Feb 2020 04:12:38 +0000</pubDate>
      <link>https://dev.to/louisshe/installing-python-3-7-4-from-source-1j5g</link>
      <guid>https://dev.to/louisshe/installing-python-3-7-4-from-source-1j5g</guid>
      <description>&lt;p&gt;I keep installing the Python from source, for two reason:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;More flexibility to manage. Cause I decide where to install it, which python module to enable.&lt;/li&gt;
&lt;li&gt;Chose the latest version. Python comes from system package manager is sometimes a older version.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Download Python source code.
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz
mkdir ~/.python3
mv Python-3.7.4.tgz ~/.python3
cd ~/.python3
tar -zxvf Python-3.7.4.tgz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Install dependencies
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Enable ssl module
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim ~/.python3/Python-3.7.4/Modules/Setup.dist
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;find keyword &lt;code&gt;ssl&lt;/code&gt; and uncomment this lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# SSL=/usr/local/ssl
# _ssl _ssl.c \
#         -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
#         -L$(SSL)/lib -lssl -lcrypto
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Compile and install
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./configure --prefix=/root/.python3/ --with-ensurepip
make
make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;Now the &lt;code&gt;python3&lt;/code&gt; and &lt;code&gt;pip&lt;/code&gt; binary are located at &lt;code&gt;~/.python3/bin&lt;/code&gt;, you can add the directory to &lt;code&gt;$PATH&lt;/code&gt; to access those commands directly.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A way to solve the handler mess of Tornado</title>
      <dc:creator>Chenglu</dc:creator>
      <pubDate>Fri, 21 Feb 2020 15:35:39 +0000</pubDate>
      <link>https://dev.to/louisshe/a-way-to-solve-the-handler-mess-of-tornado-1da1</link>
      <guid>https://dev.to/louisshe/a-way-to-solve-the-handler-mess-of-tornado-1da1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;As a web developer comming from Ruby on Rails, the "flexibility" of the handlers organization in Tornado is really painful. So I decide to organize the handlers in a Rails way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, in Tornado, the actions of a handler are exactly the http verb: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;. So when I think about how to write a handler, I have to think in the &lt;code&gt;protocol layer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, building a websites of books. The books list page and book detail page both use the same http verb &lt;code&gt;GET&lt;/code&gt;, but they have totally different logic in the backend. If we organize the handler in http verb, then the handler goese like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestHandler&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# render book list page
&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# render book detail of id
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wouldn't that be great if we could just seperate the 2 unrelated pieces of code into 2 methods, like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestHandler&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;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# render book list page
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# render book detail of id
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that is the main goal of the refactoring, to organize the handlers in a &lt;code&gt;Resource way&lt;/code&gt; instead of &lt;code&gt;Protocol way&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Luckly Ruby on Rails already done this before and have been proved to be practisable even in large projects. So I'm just gonna copy the resource abstraction of Rails, that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Handler is for manumating one resource.&lt;/li&gt;
&lt;li&gt;A Handler can have at most 7 actions. The following table shows what the action should do and how does a http request reach them.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HTTP Verb&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Handler#Action&lt;/th&gt;
&lt;th&gt;Used for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/photos&lt;/td&gt;
&lt;td&gt;photos#index&lt;/td&gt;
&lt;td&gt;display a list of all photos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/photos/new&lt;/td&gt;
&lt;td&gt;photos#new&lt;/td&gt;
&lt;td&gt;return an HTML form for creating a new photo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/photos&lt;/td&gt;
&lt;td&gt;photos#create&lt;/td&gt;
&lt;td&gt;create a new photo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/photos/:id&lt;/td&gt;
&lt;td&gt;photos#show&lt;/td&gt;
&lt;td&gt;display a specific photo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/photos/:id/edit&lt;/td&gt;
&lt;td&gt;photos#edit&lt;/td&gt;
&lt;td&gt;return an HTML form for editing a photo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PATCH/PUT&lt;/td&gt;
&lt;td&gt;/photos/:id&lt;/td&gt;
&lt;td&gt;photos#update&lt;/td&gt;
&lt;td&gt;update a specific photo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;td&gt;/photos/:id&lt;/td&gt;
&lt;td&gt;photos#destroy&lt;/td&gt;
&lt;td&gt;delete a specific photo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Then What about login? I don't see any resources in that action.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything can be resources. For login/logout, it's actually create a session and destroy a session.&lt;/p&gt;

&lt;p&gt;Now if we organizing our handlers in this way, there is no need for us to write the router's url matcher manully, a handler should populate the routes by itself, like these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BooksHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RequestHandler&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;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# render book list page
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# render book detail of id
&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tornado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="c1"&gt;# no more manully set regex
&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;BooksHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&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="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8888&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tornado&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ioloop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IOLoop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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



&lt;p&gt;Now, it should be good to visit the 2 url:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8888/books
curl http://localhost:8888/books/1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;I have already implemented this at &lt;a href="https://github.com/louis-she/tornado-resource-handler"&gt;https://github.com/louis-she/tornado-resource-handler&lt;/a&gt;. This can be directly used in existed projects, just try to write new handler in resource way, it will not broke the existing handlers.&lt;/p&gt;

&lt;p&gt;Have fun with abstracting Resources.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tornado</category>
      <category>rails</category>
      <category>resource</category>
    </item>
  </channel>
</rss>
