<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Snapshots]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>http://blog.sampingchuang.com/</link><generator>Ghost 0.6</generator><lastBuildDate>Tue, 09 Sep 2025 15:56:57 GMT</lastBuildDate><atom:link href="http://blog.sampingchuang.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Opensource GoChat - play Go in FB Messenger]]></title><description><![CDATA[<p><img src="http://blog.sampingchuang.com/content/images/2019/05/Screen-Shot-2019-05-03-at-5-29-50-PM.png#half-width" alt=""></p>

<p><a href="http://playmessengergo.com/">GoChat</a> is a project born out of my love for playing Go and boredom for my day job. It started at a time when chatbots was the new buzzword and I wanted to create a chatbot for fun. The idea is simple - you can play the board game go</p>]]></description><link>http://blog.sampingchuang.com/gochat-play-go-in-fb-messenger/</link><guid isPermaLink="false">86debab5-7b08-4b84-ba27-b6bc530a0520</guid><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Fri, 03 May 2019 09:49:51 GMT</pubDate><media:content url="http://blog.sampingchuang.com/content/images/2019/05/image-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://blog.sampingchuang.com/content/images/2019/05/image-1.png" alt="Opensource GoChat - play Go in FB Messenger"><p><img src="http://blog.sampingchuang.com/content/images/2019/05/Screen-Shot-2019-05-03-at-5-29-50-PM.png#half-width" alt="Opensource GoChat - play Go in FB Messenger"></p>

<p><a href="http://playmessengergo.com/">GoChat</a> is a project born out of my love for playing Go and boredom for my day job. It started at a time when chatbots was the new buzzword and I wanted to create a chatbot for fun. The idea is simple - you can play the board game go in FB messenger. You can start and play a game with your friends easily. </p>

<p><img src="http://blog.sampingchuang.com/content/images/2019/05/Screen-Shot-2019-05-03-at-6-15-16-PM.png" alt="Opensource GoChat - play Go in FB Messenger"></p>

<p>My first commit was on April 18, 2016 and last time I updated was December 7, 2017. With over 500 commits and countless hours, it is one of the bigger projects I’ve worked on on the side. I decided that it’s best to open source the code as I’m no longer investing my time. There are some interesting technical details that I think may be useful for other folks when looking to build similar things. </p>

<h6 id="githublink">Github link</h6>

<p>The open source code is a direct clone from my private repo, and I stripped away the sensitive password/IP information since GoChat is still up and running.</p>

<p><strong><a href="https://github.com/spchuang/GoChat/">Click here for the code</a></strong></p>

<h6 id="whatfeaturesdoesithave">What features does it have</h6>

<ul>
<li>Multi-language support</li>
<li>Play with self and play with friends</li>
<li>Play multiple games at the same time</li>
<li>Complete end to end with stone counting</li>
<li>in-game chatting with opponents</li>
<li>Simulate moves during the game</li>
</ul>

<p><img src="http://blog.sampingchuang.com/content/images/2019/05/59644611_2029754580665926_8853187538597183488_n.jpg#half-width" alt="Opensource GoChat - play Go in FB Messenger">
<img src="http://blog.sampingchuang.com/content/images/2019/05/59494654_1594738260660007_7944528211457605632_n.jpg#half-width" alt="Opensource GoChat - play Go in FB Messenger">
<img src="http://blog.sampingchuang.com/content/images/2019/05/58784933_239946243541727_8117406997378236416_n.jpg#half-width" alt="Opensource GoChat - play Go in FB Messenger">
<img src="http://blog.sampingchuang.com/content/images/2019/05/59332301_349866935875183_5412974955623088128_n.jpg#half-width" alt="Opensource GoChat - play Go in FB Messenger">
<img src="http://blog.sampingchuang.com/content/images/2019/05/59608546_331260190925242_5435449016244502528_n.jpg#half-width" alt="Opensource GoChat - play Go in FB Messenger"></p>

<p>It's funny the original intent was to build this so that maybe I can use it myself but I ended up investing way more time just building and testing and never really played with the bot. </p>

<p>While I have built many cool features, some of the most exciting things that I wanted to build didn't materialize because I moved on to other projects. Sometimes I wish if I had more time, I'll build out a game matching system so people can play with anyone else in the world and an AI mode to play with computers. Anyone, as long as you have a FB account can learn how to play Go and instantly you'll have access to the largest social network. </p>

<p>Simply building the ground work for the whole system has taken a tremendous amount of time. Given that my focus has shifted to other projects, these ideas may never come to fruition.</p>

<h6 id="highleveltechnicaldetails">High level technical details</h6>

<p>The overall architecture for the system is a standard <code>nginx</code> + <code>mysql</code> + <code>nodeJS</code>. </p>

<p>On the server side, I used <code>express</code> framework, with <code>babel</code> for compiling, <code>flow</code> for static typing, <code>sequelize.js</code> for as DB ORM, <code>chai</code> &amp; <code>mocha</code> for testing, <code>sharp</code> &amp; <code>lwip</code> for image processing, <code>AWS S3</code> for image storage, and <code>React</code> for client UI (for more complex in-game interactions).</p>

<p>For deployment, I use <code>ansible</code> for infrastructure automation, and I deployed on <a href="https://digitalocean.com">Digital Ocean</a> machines. </p>

<p>The <a href="https://github.com/spchuang/GoChat/blob/master/README.md">README</a> on the repo has a bit more in-depth technical explanations.</p>

<p>That's it. Check out the code and hopefully it'll be useful to projects you're working on.</p>]]></content:encoded></item><item><title><![CDATA[Source code for DoubleDibz]]></title><description><![CDATA[<h4 id="what">What?</h4>

<p>As I mentioned in  <a href="http://blog.sampingchuang.com/doubledibz-intro/">the previous post</a>, DoubleDibz was a craiglist-like community based market place website. I worked on it during my last year at UCLA but haven't maintained it since then. Now I want to open source the code since it could be useful for anyone working on</p>]]></description><link>http://blog.sampingchuang.com/source-code-for-doubledibz/</link><guid isPermaLink="false">5d6a3eea-0812-45f7-8821-44b3b430a80d</guid><category><![CDATA[DoubleDibz]]></category><category><![CDATA[flask]]></category><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Thu, 23 Jun 2016 06:43:20 GMT</pubDate><content:encoded><![CDATA[<h4 id="what">What?</h4>

<p>As I mentioned in  <a href="http://blog.sampingchuang.com/doubledibz-intro/">the previous post</a>, DoubleDibz was a craiglist-like community based market place website. I worked on it during my last year at UCLA but haven't maintained it since then. Now I want to open source the code since it could be useful for anyone working on similiar projects! If you are planning on building a social network on Flask, this is the project for you!</p>

<iframe width="420" height="315" src="https://www.youtube.com/embed/OrWUdpxm3kg" frameborder="0" allowfullscreen></iframe>

<p>A couple highlight for the codebase</p>

<ul>
<li>A large and complete <em>Flask</em> application serving purely as API endpoints which powers a complex Backbone application in the frontend.</li>
<li>A complete marketplace social network. This includes real-time notifications and messaging support.</li>
</ul>

<h4 id="thecode">The code</h4>

<p>Come <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL">here</a> to check out the entire source code.</p>

<h4 id="whatsincludedinthecode">What's included in the code?</h4>

<h6 id="technologyused">Technology used</h6>

<ul>
<li>Flask</li>
<li>SqlALchemy + alembic for db migration</li>
<li>a bunch of Flask libraries</li>
<li>Backbone + Marionette js</li>
<li>fabric for deployment</li>
<li>celery</li>
<li>Facebook SDK for login</li>
<li>redis</li>
<li>Nginx</li>
<li>images stored on S3</li>
</ul>

<h6 id="backendfeatures">Backend features</h6>

<ul>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/api"><strong>Purely API endpoints</strong></a>.</li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/chat"><strong>Chat</strong></a>.</li>
<li><strong>Post create</strong>. This is pretty straitforward. The highlight here is every single photo will be resized and cropped and saved on s3. See <a href="https://github.com/spchuang/DoubleDibz-tutorial/blob/master/FINAL/app/images/helpers.py">here</a>.</li>
<li><strong>Comment on posts</strong>. </li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/hashtags"><strong>hashtags</strong></a> on products. So every products could have category/hashtags. Users could explore products for a specific hashtag.</li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/notifications"><strong>Notification</strong></a>. DoubleDibz is completely social. User receives notifications when the products they subscribed to are sold or commented. </li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/blob/1751cb02d12b4e36d6de2c623f531ca24cee3516/FINAL/app/notifications/tasks.py"><strong>celery workers for notification</strong></a>. I may have over-engineered the system. I was originally concerned that if a product has a lot of subscribers and someone comments on that product, it doesn't make sense to send notification to every subscriber in the same web request. So I introduced celery to handle those tasks asynchronously.</li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/search"><strong>Search</strong></a>. A really tricky part of the app is I have a database with product posts user created on DoubleDibz but I also have a separate server which pulls products from Facebook groups. The search aggregates results from both DBs. Paginations are supported as well.</li>
<li><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/cache"><strong>caching results with redis</strong></a>. To optimize for read, I cached user notifications, post data, search results, and user data. The code is also setup to invalidate cache upon write.</li>
</ul>

<h6 id="frontend">Frontend</h6>

<p><a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/static/desktop">The frontend</a> is the most fun part of the project. I learned so much about how to structure a semi-large scale Backbone application to support all the features I wanted to make. All the things I mentioned before has a frontend counter part. You can upload photos to create a new product, look at home feed which is an infinite feed, then search for products and categories, look at product details page. You can message the seller for a product you are interested or comment on the product. You can even comment and tag your FB friends and your friends will receive notifications on FB!</p>

<p>The main thing I want to mention is <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/FINAL/app/static/desktop/js/messages">Chat</a>. This is the most complex part of the system. The challenge here is that every x seconds I'm pulling new messages from the system, and given those new messages, I need to update the correct Backbone view components. This includes updating the message count and also the message thread. </p>

<h6 id="deployment">Deployment</h6>

<ul>
<li>uwsgi configuration for the application server</li>
<li>production and staging nginx configuration</li>
<li>celery configuration </li>
<li>Fabric script for running deployment (push)</li>
</ul>

<p>Take a look! Maybe there's something you can use right away.</p>]]></content:encoded></item><item><title><![CDATA[6 things you should add to your Node projects]]></title><description><![CDATA[<h4 id="intro">Intro</h4>

<p>In the past couple weeks, I  have been developing <a href="http://www.playmessengergo.com/">GoChat</a>, a <a href="https://developers.facebook.com/docs/messenger-platform">Facebook messenger bot</a> that allows you to play a game of Go (Weiqi, Baduk) right in Facebook Messenger. It is essentially a Node server that accepts callbacks from Facebook whenever someone messages my Facebook page. </p>

<p>I have learned</p>]]></description><link>http://blog.sampingchuang.com/6-things-you-should-add-to-your-node-project/</link><guid isPermaLink="false">6a9c5c37-5237-4993-9e28-78e143c2a3df</guid><category><![CDATA[node]]></category><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Wed, 15 Jun 2016 07:02:41 GMT</pubDate><content:encoded><![CDATA[<h4 id="intro">Intro</h4>

<p>In the past couple weeks, I  have been developing <a href="http://www.playmessengergo.com/">GoChat</a>, a <a href="https://developers.facebook.com/docs/messenger-platform">Facebook messenger bot</a> that allows you to play a game of Go (Weiqi, Baduk) right in Facebook Messenger. It is essentially a Node server that accepts callbacks from Facebook whenever someone messages my Facebook page. </p>

<p>I have learned a ton from the project and I think what I used would be useful to y'all as well. I extrapolated a few things that I think any node projects improve any Node projects. Keep reading if you're working on a Node or Javascript project!</p>

<h4 id="sourcecode">Source code</h4>

<p>See <a href="https://github.com/spchuang/GoChat-tutorials/tree/master/6-things-to-add-to-your-node-projects">source code</a> for reference.</p>

<h4 id="1installbabel">1. Install Babel</h4>

<p>Everyone is using <a href="https://babeljs.io/">Babel</a> and you should too. Babel is a Javascript compiler that allows you to write modern specification of Javascript (JS6 and proposed JS7) that the V8 engine or your browsers have yet to support. <a href="https://babeljs.io/docs/learn-es2015/">This page</a> has a detailed list of nice features for ES6. There are tons of goodies like arrow functions, destructing objects and classes. </p>

<p>To take advantage of this right away, install the following. <code>babel-cli</code> is the command line interface for Babel. <code>babel-preset-es2015</code> consists of all the plugins proposed for ES6.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev babel-preset-es2015
&gt; npm install --save-dev babel-cli
</code></pre>

<p>Then create a <code>.babelrc</code> file in the root directory. This file will define the rules for the compiler.  </p>

<pre><code class="language-json">{
  "presets": ["es2015"],
}
</code></pre>

<p>Now, put all your source code in <code>.src/</code> directory. We will setup npm scripts that compiles your code to <code>.build/</code> folder.  </p>

<pre><code class="language-json">// package.json
"scripts": {
  "watch": "babel --watch=./src --out-dir=./build --source-maps inline --copy-files",
  "build": "babel ./src --out-dir=./build --source-maps inline --copy-files",
...
}
</code></pre>

<p>
When you develop, have a separate session (tmux) open that runs <code>npm run build</code>. The script will then listen to any changes in the <code>src</code> folder and auto-compiles the code. To make the process even better, add this to <code>package.json</code>. This will restart the node server when anything in <code>build</code> changes.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev nodemon
</code></pre>

<pre><code class="language-json">// package.json
"scripts": {
  "server": "nodemon build/app.js --watch build",
  ...
}
</code></pre>

<p>Awesome! Now you can use any ES6 features in your Node app. Keep in mind that you can always include <a href="https://babeljs.io/docs/plugins/">more babel plugins</a>. </p>

<h4 id="2flowtypechecker">2. Flow typechecker</h4>

<p>Like most scripting languages, Javascript is dynamically typed which means even tho you can code a bit faster but you would inevitably waste time catching stupid bugs. This is when <a href="https://flowtype.org/">Flow</a> comes in. It uses type inference and type annotation to catch those stupid bugs.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev flow
</code></pre>

<p>Once you install flow, you need to specify which files you want flow to analyze. Add the following:  </p>

<pre><code class="language-javascript">// @ flow
</code></pre>

<p>Then simply run the flow command to start checking your code!</p>

<p>You may notice that adding flow annotation is breaking babel compiling. No worries, simply install  </p>

<pre><code class="language-bash">&gt; npm install --save-dev babel-plugin-transform-flow-strip-types
</code></pre>

<p>And add the babel plugin to the <code>.babelrc</code> file  </p>

<pre><code class="language-json">{
  "presets": ["es2015"],
  "plugins": [
    "transform-flow-strip-types",
  ],
}
</code></pre>

<p>Not only does Flow help catch bugs, it also makes your code much more readable! Knowing precisely what the input format and the return type is are extremely helpful to create a mental model for the program. Imagine the following function from GoChat which renders a list of stone positions on a board image.</p>

<pre><code class="language-javascript">playStones(stones, board, cb) {  
  lwip.open(board, function(err, boardImage) {
    if(err) {
      error('Cannot open board image', err);
      cb(err);
    } else {
      _playStonesHelper(stones, boardImage, cb);
    }
  });
}
</code></pre>

<p>If I'm brand new to the code base this would be going through my head, "What are <code>stones</code>? Are they objects or array? What properties does it have? <code>cb</code> seems like callback but can I be exactly sure? Oh yeah okay it is..." As you see, the code could be interpreted in different ways and you are required to trace through other functions to have a better understanding.</p>

<p>Now, take a look at how this would look like using flow.  </p>

<pre><code class="language-javascript">type StoneColor = 'black' | 'white';  
type Stone = {  
  x: number,
  y: number,
  color: StoneColor,
};

playStones(stones: Array&lt;Stone&gt;, board: string, cb: Function): void {  
  lwip.open(board, function(err, boardImage) {
    if(err) {
      error('Cannot open board image', err);
      cb(err);
    } else {
      _playStonesHelper(stones, boardImage, cb);
    }
  });
}
</code></pre>

<p>Much cleaner.</p>

<h4 id="3lintingwitheslint">3. Linting with ESLint</h4>

<p>Programmers are lazy and prone to make careless mistakes. And that's okay, as long as there are programs that clean up our messes. Linting tools are designed to do exactly that. <code>JSLint</code> and <a href="http://eslint.org/"><code>ESLint</code></a> are both popular for javascript but the latter offers much better flexibility to add custom linting rules.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev eslint
</code></pre>

<p>Then add a <code>.eslintrc</code> file. Then you can define the rules you want from all the <a href="http://eslint.org/docs/rules/">supported rules</a>.</p>

<p>One tricky thing here is that since we are using Flow, our source code are not proper Javascript so ESLint will have parsing issues. Good news is that ESLint allows you to define custom parsers to transform into code that ESLint could understand.</p>

<pre><code class="language-bash">&gt; npm install --save-dev babel-eslint
</code></pre>

<p>Then in <code>.eslintrc</code>, define...  </p>

<pre><code class="language-json">{
  "parser": "babel-eslint",
  "env": {
    // in CommonJS
    "node": true
  },
  "rules": {
    ...
  }
}
</code></pre>

<p>ESlint is great for maintaining consistent coding styles. Personally, I prefer using trailing commas and the rule <code>comma-dangle</code> has been wonders. By running <code>eslint src --fix</code> with the <code>fix</code> param, ESLint even auto fixes places where I don't have trailing commas.</p>

<p>If you ever feel overwhelmed and not sure what rules to you use, you can always download the <a href="https://github.com/walmartlabs/eslint-config-defaults">standard</a> rule sets and call it a day.</p>

<h4 id="4invariant">4. invariant</h4>

<p><a href="https://github.com/zertosh/invariant">Invariant</a> is a little handy module that I used very heavily in my app. </p>

<pre><code class="language-bash">&gt; npm install --save invariant
</code></pre>

<p>Without getting into too much <a href="https://en.wikipedia.org/wiki/Design_by_contract">details</a> of its importance in Software Engineering, using invariants helps me keep track of the correctness and assumptions of my functions. I use invariants a lot to assert the type and data correctness of function arguments and also to verify an action is proper given the current application/user state. For example, I have a series of functions that are only applicable to users currently in a game, so I would throw an invariant in these functions:  </p>

<pre><code class="language-javascript">async resignGame(user: User): Promise&lt;void&gt; {  
  invariant(user.isPlaying(), 'User should be playing');
  ...
}
</code></pre>

<p>This not only catches careless errors but is a great code documentation for me and my partner. Install now and try it for yourself!</p>

<h4 id="5asyncandawait">5. async and await</h4>

<p>Javascript is asynchronous and single-threaded. This means for many operations such as talking to the DB, making a http request, the application will kickoff the function and then process thread will "unblock" itself and run on something else. That means your code will most likely have a bunch of <a href="https://www.youtube.com/watch?v=ay0phloFcMo">callbacks</a>. A hell of nested callbacks!  </p>

<pre><code class="language-javascript">function doSomething(callback): void {  
  doSomethingFirst((result1) =&gt; {
    okay(result1);
    doSomethingSecond((result2) =&gt; {
      more(result2);
      doSomethingThird((result3) =&gt; {
        callback(result3);
      });
    });
  });
}
</code></pre>

<p>There are methods to make the code cleaner when you want to avoid nested callback hells - avoid nesting functions, modularize the callbacks, etc. Personally, callbacks just make make my code much more unreadable and makes it difficult to handle exceptions. I prefer writing serial code and the <em>framework</em> should handle the asynchronous processing.</p>

<p>Fortunately, you can use await and async functions proposed in ES7 features. The above code will be equivalent to  </p>

<pre><code class="language-javascript">async function doSomething(): Promise&lt;void&gt; {  
  const result1 = await doSomethingFirst();
  okay(result1);
  const result2 = await doSomethingSecond();
  more(result2);
  return await doSomethingThird();
}
</code></pre>

<p>Isn't that much nicer? It is very clear how the logic flows and the code is much more concise. </p>

<p>You can use it right away using Babel compiler. Under the hood, it will convert async/await to generators.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev babel-plugin-syntax-async-functions
&gt; npm install --save-dev babel-plugin-transform-async-to-module-method
</code></pre>

<p>And update your <code>.babel</code>  </p>

<pre><code class="language-json">{
  "presets": ["es2015"],
  "plugins": [
    ...
    "syntax-async-functions",
    ["transform-async-to-module-method", {
      "module": "bluebird",
      "method": "coroutine"
     }]
  ],
}
</code></pre>

<p>Finally, since v8 doesn't provide generator functions, you need to import the Babel polyfill environment which adds a bunch of ES2015 features to the global scope.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev babel-polyfill
</code></pre>

<p>Then add to <code>app.js</code>  </p>

<pre><code class="language-javascript">import 'babel-polyfill';  
</code></pre>

<h4 id="6testwithmocha">6. Test with Mocha</h4>

<p>Always test your app. It's easy to forget about it and only focus on the business logic but trust me, at the end of the day, the only thing that makes me sleep at night is knowing that my code passes all the tests. When your app become more complicated, unit tests or integrations tests ensure any new changes don't result in regression or bugs. </p>

<p>For testing in Javascript there are plenty of options but I really enjoy using <a href="https://mochajs.org/">Mocha</a> for its simplicaity.  </p>

<pre><code class="language-bash">&gt; npm install --save-dev mocha
&gt; npm install --save-dev chai 
</code></pre>

<p>A tricky thing I had was being able to use async/await for my unit tests. It's actually quite simple, when starting the mocha script, you could specify Babel as the compiler. It will then compile the code on the fly and run the tests.  </p>

<pre><code class="language-json">// package.json
"scripts": {
  "test": "NODE_ENV=test mocha --compilers js:babel-register",
  ...
}
</code></pre>

<p>Let's see how to make a simple integration test that checks <code>GET /</code> returns <code>200</code>. Note that I'm starting a new instance of server for each test case. This makes sure theres no order dependency and each test starts with a clean state.</p>

<pre><code class="language-javascript">// test/basicServerTest.js
import 'babel-polyfill';  
import {expect} from 'chai';  
import {mochaAsync} from './TestHelpers';  
import request from "supertest-as-promised";  
import makeServer from '../src/server';

describe('Basic server test', function() {  
  this.timeout(1000);
  var server;
  beforeEach(mochaAsync(async () =&gt; {
    server = await makeServer(true /* silent */);
  }));

  afterEach(function (done) {
    server.close(done);
  });

  it('Server healthy', mochaAsync(async () =&gt; {
    await request(server).get('/')
      .expect(200);
  }));
});
</code></pre>

<p>Then run the test.  </p>

<pre><code class="language-bash">&gt; npm run test
npm run test

&gt; Node_tutorial@1.0.0 test /Users/spchuang/github/GoChat-tutorial/6-things-to-add-to-your-node-projects
&gt; NODE_ENV=test mocha --compilers js:babel-register



  Basic server test
    ✓ Server healthy (44ms)


  1 passing (212ms)
</code></pre>

<h3 id="thatsit">That's it!</h3>

<p>Alright, that's it!</p>

<p>One last thing, I generally want to run flow, lint and tests together when I develop. This is the handy script I use:  </p>

<pre><code class="language-json">// package.json
"scripts": {
  "check": "npm run lint &amp;&amp; npm run flow &amp;&amp; npm run test",
  ...
}
</code></pre>

<p>I hope you can try them out for your Node project because they have certain made my Node development a much smoother experience!</p>]]></content:encoded></item><item><title><![CDATA[Setup User Authentication in Flask]]></title><description><![CDATA[<h3 id="intro">Intro</h3>

<p>In the <a href="http://blog.sampingchuang.com/setup-user-authentication-in-flask/(http://blog.sampingchuang.com/flask-hello-world/)">previous tutorial</a>, I showed how to create the simplest possible Flask application - hello world. Unfortunately, the example application was too simple to show the full potential of the <a href="http://blog.sampingchuang.com/setup-user-authentication-in-flask/(http://blog.sampingchuang.com/structure-a-large-flask-api-backend-app/)">application structure</a>, something I want to show in this post.</p>

<p>In this tutorial I will continue from the</p>]]></description><link>http://blog.sampingchuang.com/setup-user-authentication-in-flask/</link><guid isPermaLink="false">502bc41d-801e-41b8-af9a-3d2e3b0d93a3</guid><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Sun, 30 Aug 2015 00:42:00 GMT</pubDate><content:encoded><![CDATA[<h3 id="intro">Intro</h3>

<p>In the <a href="http://blog.sampingchuang.com/setup-user-authentication-in-flask/(http://blog.sampingchuang.com/flask-hello-world/)">previous tutorial</a>, I showed how to create the simplest possible Flask application - hello world. Unfortunately, the example application was too simple to show the full potential of the <a href="http://blog.sampingchuang.com/setup-user-authentication-in-flask/(http://blog.sampingchuang.com/structure-a-large-flask-api-backend-app/)">application structure</a>, something I want to show in this post.</p>

<p>In this tutorial I will continue from the same code and develop a simple user authentication system. Users are the core to every modern-day application, and creating a user system is certainly the first step every develop takes on his or her journey to make the next world-changing application. You can start here.</p>

<p>To get a complete sense of the code base from before, please see the <a href="http://blog.sampingchuang.com/setup-user-authentication-in-flask/(https://github.com/spchuang/DoubleDibz-tutorial/tree/master/flask_hello_world)">source code on Github</a>.</p>

<h4 id="sourcecode">Source code</h4>

<p>You can download the source code on <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/flask_simple_authentication">gibhub</a>.</p>

<h3 id="sowhatdoigetintheend">So what do I get in the end?</h3>

<p>Good question. I will show how to create models with <code>Flask-SQLAlchemy</code>, do form validations using <code>Flask-WTF</code>, handling login sessions with <code>Flask-Login</code> and I would also show example usage of <code>Flask-Script.</code> There will also be code for the UI, but it will be quite minimal since this tutorial is mainly concerned with developing Flask. In the end, you'll be able to signup for a new user, login the user, refresh the page and you'll still be logged in, and then finally when you may logout, which will clear the user session from the server.</p>

<p>To be more specific, the following will happen during this tutorial:</p>

<ul>
<li>create a <code>user</code> table in the database (sqlite in this case). The table contains fields like first name, last name, email address, and user name and password. The password will be hashed for security reasons.</li>
<li>create 2 WTForms, one for user logins and one for signup. They will be used for validating post data from logins and signup.</li>
<li>create 4 authentication endpoints: <code>/api/auth/verify_auth</code>, <code>/api/auth/login</code>, <code>/api/auth/logout</code>, and <code>/api/auth/signup</code>.</li>
<li>create a light UI in <code>jquery</code> to demonstrate the aforementioned authentication APIs.</li>
</ul>

<p>Alright, that's too much talking and not enough coding. Lets get right to it.</p>

<h4 id="step1installdependencies">Step 1. Install dependencies</h4>

<p>Flask is a very flexible framework and offers plenty of different extensions for things like logging, form validation and database abstraction (ORM). In this tutorial, I'm going to show the use of 4 commonly-used Flask extensions:</p>

<ul>
<li><a href="https://flask-wtf.readthedocs.org/en/latest/">Flask-WTF</a> : integration with <a href="http://wtforms.simplecodes.com/docs/">WTForm</a>, which offers useful features like form validation and CSRF handling to prevent XSS attacks.</li>
<li><a href="https://pythonhosted.org/Flask-SQLAlchemy/">Flask-SQALAlchemy</a> : Integration to <a href="http://www.sqlalchemy.org/">SQLAlchemy</a>, a very simple and powerful library for database abstraction. </li>
<li><a href="http://flask-script.readthedocs.org/en/latest/">Flask-Script</a> : Useful extension for creating external scripts in Flask.</li>
<li><a href="https://flask-login.readthedocs.org/en/latest/">Flask-Login</a>: provides user session management for Flask.</li>
</ul>

<pre><code class="language-bash">$ pip install Flask-Script
$ pip install Flask-SQLAlchemy
$ pip install Flask-WTF
$ pip install Flask-Login
$ pip freeze &gt; requirements.txt
</code></pre>

<h4 id="step2createthefiles">Step 2: Create the files</h4>

<p>To create a user authentication system, we would create a a frontend module for serving the html pages and a user module (folder) for handling user validation and database access. Then we would add a another API <code>auth.py</code> for authentication endpoints like logging in and signing out. To make everything work together, we'll create a few helper functions along the way.  </p>

<pre><code class="language-bash">$ cd DoubleDibz
$ touch manage.py
$ mkdir app/users
$ mkdir app/static
$ mkdir app/frontend
$ touch app/frontend/__init__.py
$ touch app/frontend/controller.py
$ touch app/models.py
$ touch app/common/helpers.py
$ touch app/common/response.py
$ touch app/users/UserModels.py
$ touch app/users/UserConstants.py
$ touch app/users/UserForms.py
$ touch app/users/__init__.py
$ touch app/api/auth.py
</code></pre>

<p>Our current structure:  </p>

<pre><code class="language-bash">DoubleDibz  
├── app
│   ├── __init__.py
│   ├── api
│   │   ├── __init__.py
│   │   ├── auth.py
│   │   └── helloworld.py
│   ├── app.py
│   ├── common
│   │   ├── __init__.py
│   │   ├── constants.py
│   │   ├── helpers.py
│   │   └── response.py
│   ├── config.py
│   ├── extensions.py
│   ├── frontend
│   │   ├── __init__.py
│   │   └── controller.py
│   ├── models.py
│   ├── static
│   ├── templates
│   └── users
│       ├── UserConstants.py
│       ├── UserForms.py
│       ├── UserModels.py
│       └── __init__.py
├── manage.py
├── requirements.txt
└── run.py
</code></pre>

<p>I won't talk about every single line of code added or modified, such as <code>app/common/helpers.py</code> and <code>app/common/response.py</code>, but they are all crucial in the making of the system. So to get a sense of the bigger picture, take a look at the <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/flask_simple_authentication">final code</a>.</p>

<h4 id="step3editextensionspyandapppy">Step 3: Edit <code>extensions.py</code> and <code>app.py</code></h4>

<p>Initialize <code>Flask-SQLAlchemy</code>, <code>Flask-WTF</code>  and <code>Flask-Login</code> extensions.  </p>

<pre><code class="language-bash">$ vim app/extensions.py
</code></pre>

<p>Place the following  </p>

<pre><code class="language-python"># Flask-SQLAlchemy extension instance
from flask.ext.sqlalchemy import SQLAlchemy  
db = SQLAlchemy()

# Flask-Login
from flask.ext.login import LoginManager  
login_manager = LoginManager()

# Flask-WTF csrf protection
from flask_wtf.csrf import CsrfProtect  
csrf = CsrfProtect()  
</code></pre>

<p>These code would the extension objects. Next we would need to initialize the extension with the our Flask application.  </p>

<pre><code class="language-bash">$ vim app/app.py
</code></pre>

<p>Add this to top  </p>

<pre><code class="language-python">from .models import User  
from .extensions import db, login_manager, csrf  
</code></pre>

<p>and add the following in the function <code>configure_extensions()</code>  </p>

<pre><code class="language-python">def configure_extensions(app):  
   # flask-sqlalchemy
   db.init_app(app)

   # flask-login
   login_manager.login_view = 'frontend.index'
   login_manager.refresh_view = 'frontend.index'

   @login_manager.user_loader
   def load_user(id):
      return User.query.get(id)

   login_manager.setup_app(app)

   # flask-wtf
   csrf.init_app(app)
</code></pre>

<h4 id="step4createusermodelspy">Step 4: create <code>UserModels.py</code></h4>

<p>Okay, now that we have initialized our extensions. We can start with the user model. In <code>SQLAlchemy</code>, each data model correspond one-to-one with a table in the database: <code>User</code> model will contain all the relevant information as a user and most importantly the credentials for logging in on the site.  </p>

<pre><code class="language-python">from werkzeug import generate_password_hash, check_password_hash

from flask.ext.login import UserMixin  
from ..common.helpers import JsonSerializer, get_current_time  
from ..extensions import db

import UserConstants

class UserJsonSerializer(JsonSerializer):  
    __json_public__ = ['id', 'email', 'user_name']
    __json_modifiers__ = {
      'role_code' : ['role', (lambda code : UserConstants.USER_ROLE[code])]
    }

class User(db.Model, UserMixin, UserJsonSerializer):

   __tablename__ = "user"
   def __repr__(self):
      return '&lt;User %r&gt;' % (self.user_name)

   id            = db.Column(db.Integer, primary_key = True)
   first_name    = db.Column(db.String(UserConstants.STRING_LEN), nullable=False)
   last_name     = db.Column(db.String(UserConstants.STRING_LEN), nullable=False)
   user_name     = db.Column(db.String(UserConstants.STRING_LEN),  index = True, unique = True, nullable=False)
   email         = db.Column(db.String(UserConstants.STRING_LEN), index = True, unique = True, nullable=False)
   created_on    = db.Column(db.DateTime, nullable=False, default = get_current_time)
   role_code = db.Column(db.SmallInteger, default=UserConstants.USER, nullable=False)

   # User Password
   _password = db.Column('password', db.String(UserConstants.PW_STRING_LEN), nullable=False)

   def _get_password(self):
      return self._password

   def _set_password(self, password):
      self._password = generate_password_hash(password)

   password = db.synonym('_password',
                          descriptor=property(_get_password,
                                              _set_password))

   def check_password(self, password):
      if self.password is None:
         return False
      return check_password_hash(self.password, password)

   # methods
   @classmethod
   def authenticate(cls, user_name, password):
      user = User.query.filter(db.or_(User.user_name == user_name)).first()

      if user:
         authenticated = user.check_password(password)
      else:
         authenticated = False
      return user, authenticated

   @classmethod
   def is_user_name_taken(cls, user_name):
      return db.session.query(db.exists().where(User.user_name==user_name)).scalar()

   @classmethod
   def is_email_taken(cls, email_address):
      return db.session.query(db.exists().where(User.email==email_address)).scalar()
</code></pre>

<p>A couple things are worth talking about here.</p>

<ul>
<li><code>password</code> field: notice how the password field is defined using SQLAlchemy's <a href="http://docs.sqlalchemy.org/en/rel_1_0/orm/mapped_attributes.html#synonyms">synonym</a> and descriptor. <code>password</code> is essentially mirroring <code>_password</code> attribute and we use descriptor to define how 
<em>getting password</em> and <em>setting password</em> behaves, as defined in <code>_get_password</code> and <code>_set_password</code> respectively. When setting the password, instead of saving the user password string, we save the hashed password in the db using <code>generate_password_hash</code>. </li>
<li><code>UserJsonSerializer</code> mixin: inherited from <code>JsonSerializerr</code> (see <a href="https://github.com/spchuang/DoubleDibz-tutorial/blob/master/flask_simple_authentication/app/common/helpers.py"><code>app/common/helpers</code></a> for definition). This handy mixin provides the <code>to_json</code> function which will deserialize an instance of the model to json format. Example (after setting up <code>Flask-Script</code> in step 5):</li>
</ul>

<pre><code class="language-bash">$ python manage.py shell
&gt;&gt;&gt; user = models.User.query.all()[0];
&gt;&gt;&gt; user.to_json()
{'role': 'user', 'user_name': u'spchuang', 'id': 1, 'email': u"test@gmail.com"}
</code></pre>

<ul>
<li><code>UserMixin</code> Mixin: provides default implementation of what would be required for Flask-Login.</li>
</ul>

<h4 id="step51createthedatabasewithflaskscript">Step 5.1 : create the database with <code>Flask-Script</code></h4>

<p>Now that we have the user models, we can use it to create the actual database table. To do this, we're going to use <code>Flask-script</code>. This extension allows us to create handy scripts for things like initilizing the database and running a shell with the application context.</p>

<pre><code class="language-bash">vim manager.py  
</code></pre>

<pre><code class="language-python">from flask.ext.script import Manager, Shell, Server  
from flask import current_app  
from app import create_app  
from app.extensions import db  
import app.models as Models  
from app.config import DefaultConfig  
import os

def create_my_app(config=DefaultConfig):  
  return create_app(config)

manager = Manager(create_my_app)

# runs Flask development server locally at port 5000
manager.add_command("runserver", Server(host="0.0.0.0", port=5000))

# start a Python shell with contexts of the Flask application
@manager.shell
def make_shell_context():  
   return dict(app=current_app, db=db, models=Models)

# init/reset database
@manager.command
def initdb():  
    db.drop_all(bind=None)
    db.create_all(bind=None)

    # add sample user
    user = Models.User(
            first_name=u'Sam',
            last_name=u'Chuang',
            user_name=u'spchuang',
            password=u'123456',
            email=u"test@gmail.com") 
    db.session.add(user)
    db.session.commit()


if __name__ == "__main__":  
    manager.run()
</code></pre>

<p>Now, by running the following command, you can initialize the database to create the User table and also an example user, which we'll use to test or login later.  </p>

<pre><code class="language-bash">$ python manage.py initdb
</code></pre>

<p>You should see a file being created in<code>/tmp/test.db</code>, as we configured SQLAlchemy to use a sqlite db at this path. To determine whether or not the user is actually created, you can take a use of Flask-Script's shell commands.  </p>

<pre><code class="language-bash">$ python manage.py shell
&gt;&gt;&gt; users = models.User.query.all()
&gt;&gt;&gt; print users
[&lt;User u'spchuang'&gt;]
&gt;&gt;&gt; print users[0].password
pbkdf2:sha1:1000$x8kBSPNw$92b15d93720e001a1cf6343f2b589cff0b198024  
</code></pre>

<p>Notice how it shows the username of the user. This is defined in <code>__repr__</code> in the User models object. Also, see how the password field is a hashed view. Besides using the manager shell, you can also examine db data using the sqlite3 interface:  </p>

<pre><code class="language-bash">$ sqlite3 /tmp/test.db 
SQLite version 3.8.3 2014-02-03 14:04:11  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite&gt; select user_name,email from user;  
spchuang|test@gmail.com'  
sqlite&gt; select * from sqlite_master where type='table';  
table|user|user|2|CREATE TABLE user (  
    id INTEGER NOT NULL, 
    first_name VARCHAR(64) NOT NULL, 
    last_name VARCHAR(64) NOT NULL, 
    user_name VARCHAR(64) NOT NULL, 
    email VARCHAR(64) NOT NULL, 
    created_on DATETIME NOT NULL, 
    password VARCHAR(80) NOT NULL, 
    role_code SMALLINT NOT NULL, 
    PRIMARY KEY (id)
)
</code></pre>

<h4 id="step52testingthedatabaseandmodels">Step 5.2: Testing the database and models</h4>

<p>So far we have defined the User model and created the user table. Lets take a step back and do some testing to make sure everything is working correctly so far. It is good to break a meaty project into smaller, testable components. This allows us to establish baselines as we go. </p>

<pre><code class="language-bash">$ python manage.py shell
&gt;&gt;&gt; user, authenticated = models.User.authenticate('random_user', 'test')
&gt;&gt;&gt; print user, authenticated
None False  
&gt;&gt;&gt; user, authenticated = models.User.authenticate('spchuang', 'test')
&gt;&gt;&gt; print user, authenticated
&lt;User u'spchuang'&gt; False  
&gt;&gt;&gt; user, authenticated = models.User.authenticate('spchuang', '123456')
&gt;&gt;&gt; print user, authenticated
&lt;User u'spchuang'&gt; True  
&gt;&gt;&gt; print models.User.is_user_name_taken('spchuang')
True  
&gt;&gt;&gt; print models.User.is_email_taken('test@gmail.com')
True  
</code></pre>

<p>Sweet, it seems like all the functions are working as we expected. As a general note, validating functions in shell is very handy and is a quick way to iterate on the code. But going forward, we'll probably want to add unit tests to cover those logics since it doesn't scale to hand test them everytime. Automated testings guarantees the code to work for all the test coverages and show whether new code has any regression (breaks test cases). Testing is outside the scope of this tutorial, but I'll probably find sometime to give an example how I could do testing in Flask.</p>

<h4 id="step6createuserformspy">Step 6: create <code>UserForms.py</code></h4>

<p>The next step is defining our form validation logic. Data checking is center to everything we do. Whenever we receive some data from the user. We want to make sure we have all the values needed to create a user and for logging in.</p>

<pre><code class="language-python">from flask_wtf import Form  
from wtforms import (BooleanField, TextField, HiddenField, PasswordField,  
   DateTimeField, validators, IntegerField, SubmitField)
import UserConstants

class LoginForm(Form):  
   login = TextField('user_name', [validators.Required()])
   password  = TextField('password',  [validators.Required()])
   remember_me = BooleanField('remember_me', default = False)

class SignupForm(Form):  
   user_name   = TextField('user_name',   [
      validators.Length(
         min = UserConstants.MIN_USERNAME_LEN, 
         max = UserConstants.MAX_USERNAME_LEN
      ),
      validators.Regexp(
         "^[a-zA-Z0-9]*$",
         message="Username can only contain letters and numbers"
      )
   ])
   first_name  = TextField('first_name', [validators.Required()])
   last_name   = TextField('last_name', [validators.Required()])
   email       = TextField('email', [validators.Required(), validators.Email()])
   password    = PasswordField(
      'New Password', 
      [validators.Length(min=UserConstants.MIN_PASSWORD_LEN,max=UserConstants.MAX_PASSWORD_LEN)]
   )
   confirm     = PasswordField('Repeat Password', [
      validators.Required(),
      validators.EqualTo('password', message='Passwords must match')
   ])
</code></pre>

<p>It is pretty straight forward. We define a form for login and another for signup. <code>Flask-WTF</code> allows us to define the fields and specific validations we want for each field. Some default validators are provided but we could also define our own. See the validation logic for username, in which I restrict it to only letters and number using regular expression.</p>

<h4 id="step7createauthenticationendpointapiauthpy">Step 7 : create authentication endpoint <code>api/auth.py</code></h4>

<pre><code class="language-bash">vim app/api/auth.py  
</code></pre>

<pre><code class="language-python"># Users API for authentication
'''  
   Users API for authentication
'''  
from flask import (Blueprint, render_template, current_app, request,  
                   flash, url_for, redirect, session, abort, jsonify)

from flask.ext.login import login_required, login_user, current_user, logout_user, confirm_login, login_fresh  
from ..common import Response  
from ..extensions import db

from ..users import User, SignupForm, LoginForm

auth = Blueprint('auth', __name__, url_prefix='/api/auth')

@auth.route('/verify_auth', methods=['GET'])
@login_required
def verify_auth():  
   return Response.make_data_resp(data=current_user.to_json())

@auth.route('/login', methods=['POST'])
def login():  
   """ POST only operation. check login form. Log user in """
   if current_user.is_authenticated():
      return Response.make_success_resp(msg="You are already logged in")

   form = LoginForm()
   if form.validate_on_submit():
      user, authenticated = User.authenticate(form.login.data,
                                              form.password.data)
      if user :
         if authenticated:
            login_user(user, remember=form.remember_me.data)
            return Response.make_data_resp(data=current_user.to_json(), msg="You have successfully logged in")
         else:
            return Response.make_error_resp(msg="Invalid username or password", type="Wrong Authentication", code=422)
      else:
         return Response.make_error_resp(msg="Username does not exist", type="Wrong Authentication", code=422)

   return Response.make_form_error_resp(form=form)


@auth.route('/logout', methods=['POST'])
@login_required
def logout():  
   """ logout user """
   session.pop('login', None)
   logout_user()
   return Response.make_success_resp(msg="You have successfully logged out")

@auth.route('/signup', methods=['POST'])
def signup():  
   if current_user.is_authenticated():
      return make_success_resp("You're already signed up")

   form = SignupForm()

   if form.validate_on_submit():
      # check if user_name or email is taken
      if User.is_user_name_taken(form.user_name.data):
         return Response.make_error_resp(msg="This username is already taken!", code=409)
      if User.is_email_taken(form.email.data):
         return Response.make_error_resp(msg="This email is already taken!", code=409)

      try:
         # create new user
         user = User()
         form.populate_obj(user)

         db.session.add(user)
         db.session.commit()

      except Exception as e:
         return Response.make_exception_resp(exception=e)

      # log the user in
      login_user(user)
      return Response.make_success_resp(msg="You successfully signed up! Please check your email for further verification.")

   return Response.make_form_error_resp(form=form)
</code></pre>

<p>Here we define 4 endpoints that we would use for authentication. You may wonder why do we need <code>/api/auth/verify_auth</code>. As I mentioned before, we are creating a pure API backend with frontend powered in javascript. Therefore, as the javascript application first start we need to determine whether the user is already logged in or not. This endpoint does just that - allows the frontend to bootstrap application state. You'll see a quick example in the UI section below. </p>

<p>The <code>Form.validate_on_submit</code> does what the name suggests - validate the input forms. It would make sure the every field passes the validation rules we defined for it and would fail otherwise. </p>

<p>By default, every <code>POST</code> request would have csrf protection on due to <code>Flask-WTF</code> settings. Cross-Site Request Forgery is unlike other hacking techniques where malicious users fake their credentials and behave on your behalf. Instead, hackers injects malicious scripts to trick your browser in doing an unwanted action on a website you're already logged in. In the website's perspective, the action is genuine and trust worthy since it came from you directly even though your browser did it unexpectedly. There are many common fixes for this - one of the which is CSRF protection. Flask-WTF will verify a hashed token for every POST request.</p>

<p>Update <code>app.py</code> to include the blueprint for our authentication API.  </p>

<pre><code class="language-python"># in app/app.py
...
from .api import helloworld, auth  
...
DEFAULT_BLUEPRINTS = [  
   helloworld,
   auth,
]
</code></pre>

<h4 id="step8basicfrontend">Step 8: basic frontend</h4>

<p>In this last part, I'll talk briefly on implementing a simple frontend that talks to the backend via jquery</p>

<p>First, Serve the static HTML with a new controller  </p>

<pre><code class="language-bash">$ vim app/frontend/controller.py
</code></pre>

<pre><code class="language-python">from flask import (Flask, Blueprint, render_template, current_app, request,  
                   flash, url_for, redirect, session, abort, jsonify, send_from_directory)

frontend = Blueprint('frontend', __name__)

@frontend.route('/')
@frontend.route('/&lt;path:path&gt;')
def index(path=None):  
   return render_template('app.html')
</code></pre>

<p>This controller is responsible for serving static pages, in this case, <code>app/template/app.html</code>.  </p>

<p>Now Copy the <code>app/templates</code> and <code>app/static</code> folders from github. Open the file, and notice how we load two javascript files, jquery and our custom javascript file which will be used to communicate with the backend. We will use bootstrap for styles.  </p>

<pre><code class="language-html">// app/templates/app.html
...

{% block js_btm %}
&lt;!-- Put javascript here !--&gt;

   &lt;script src="/static/desktop/vendors/jquery.js"&gt;&lt;/script&gt;
   &lt;script src="/static/desktop/js/main.js"&gt;&lt;/script&gt;

{% endblock %}
</code></pre>

<p>So our game plan is all in <code>/static/desktop/js/main.js</code>. </p>

<pre><code class="language-javascript">// setup csrf token for all ajax calls
var csrftoken = $('meta[name=csrf-token]').attr('content');  
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
         xhr.setRequestHeader("X-CSRFToken", csrftoken);
      }
    }
});

$(document).ready(function(){
   // initial check to see if user is logged in or not
   updateAuthStatus();



   // setup logged in view
   $('#logged-in-view button').click(function(){
      logout()
         .done(function(response){
            showLoggedout()
         }).fail(function(response){
            showLoggedIn();
         });
   });

   // setup signup view
   $('#signup-view #signup-form').submit(function(e) {
      e.preventDefault();
      var form = $(this);
      var signupData = extractFormInput(form);

      signup(signupData)
         .done(function(response){
            alert('You just created a new user');
            form.trigger('reset');
            updateAuthStatus();
         }).fail(function(response){
            alert('Something went wrong');
         });

   });
});

// helpers
function updateAuth() {  
   verifyAuth()
      .done(function(response){
         showLoggedIn(response.data.user_name)
      }).fail(function(response){
         showLoggedout()
      });
}
function extractFormInput(form) {  
   var inputs = form.serializeArray();
   var data = {};
   $.each(inputs, function(index, input) {
      data[input.name] = input.value;
   });
   return data;
}

function showLoggedIn(username) {  
   // show logged in view and show username
   $("#logged-in-view span").text(username);
   $("#logged-out-view").addClass('hidden');
   $("#logged-in-view").removeClass('hidden');
}

function showLoggedout() {  
   // show logged out view
   $("#logged-out-view").removeClass('hidden');
   $("#logged-in-view").addClass('hidden');
}

// API calls
function verifyAuth(callback) {  
   var url = '/api/auth/verify_auth';
   return $.get(url);
}

function login(loginData){  
   var url = '/api/auth/login';
   return $.post(url, loginData);
}

function logout() {  
   var url = '/api/auth/logout';
   return $.post(url);
}

function signup(signupData) {  
   var url = '/api/auth/signup';
   return $.post(url, signupData);
}
</code></pre>

<p>Login view <br>
<img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-28-at-12-03-07-AM.png" alt=""></p>

<p>After logging in <br>
<img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-28-at-12-03-11-AM.png" alt=""></p>

<p>Signup view <br>
<img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-28-at-12-05-37-AM.png" alt=""></p>

<p>Thats it! Now you have created a simple user system in flask that could create new users and log existing users in. In a following post, I will work on the UI side of things and show example of using Backbone to power the user authentication.</p>]]></content:encoded></item><item><title><![CDATA[Setup a simple hello world Flask API App]]></title><description><![CDATA[<h3 id="intro">Intro</h3>

<p>In this tutorial, I will create a basic hello-world Flask application using the file structure from the <a href="http://blog.sampingchuang.com/structure-a-large-flask-api-backend-app/">previous tutorial</a>. This application will simply create an api endpoint at <code>api/helloworld/helloworld</code> and return a message <code>helloworld</code> in json format.</p>

<h4 id="sourcecode">Source code</h4>

<p>You can download the source code on <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/flask_hello_world">gibhub</a></p>]]></description><link>http://blog.sampingchuang.com/flask-hello-world/</link><guid isPermaLink="false">c109583d-ee0a-4cdb-9f61-b6dae14b0d96</guid><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Mon, 24 Aug 2015 06:45:38 GMT</pubDate><content:encoded><![CDATA[<h3 id="intro">Intro</h3>

<p>In this tutorial, I will create a basic hello-world Flask application using the file structure from the <a href="http://blog.sampingchuang.com/structure-a-large-flask-api-backend-app/">previous tutorial</a>. This application will simply create an api endpoint at <code>api/helloworld/helloworld</code> and return a message <code>helloworld</code> in json format.</p>

<h4 id="sourcecode">Source code</h4>

<p>You can download the source code on <a href="https://github.com/spchuang/DoubleDibz-tutorial/tree/master/flask_hello_world">gibhub</a>.</p>

<h4 id="setuptheenvironmentandinstalldependencies">Setup the environment and install dependencies</h4>

<p>Lets create the application folder first. For the purposes of this tutorial, I'll refer to our application as <code>DoubleDibz</code>.</p>

<pre><code class="language-bash">$ cd [to where you want your application folder to be]
$ mkdir DoubleDibz
</code></pre>

<p>Before creating any more folders and files, we would need to setup the environment. Here I am assuming you guys have <code>python</code>, <code>pip</code>, and <code>virtualenv</code> installed already. If not, take a look <a href="https://www.digitalocean.com/community/tutorials/common-python-tools-using-virtualenv-installing-with-pip-and-managing-packages">here</a>. It is generally a best practice to not install dependencies in the Python global packages, and instead install them in an isolated environment for each of your applications. </p>

<p>To create the virtual environment for DoubleDibz, do the following:</p>

<pre><code class="language-bash">$ cd DoubleDibz
$ virtualenv .pyenv
New python executable in .pyenv/bin/python  
Installing setuptools, pip...done.  
</code></pre>

<p>Now the virtual environment resides in the <code>.pyenv/</code> folder. Lets activate the environment!</p>

<pre><code class="language-bash">$ source .pyenv/bin/activate
</code></pre>

<p>At this point, the name of the virtual environment (<code>.pyenv</code>) should appear on the left of your command prompt:</p>

<pre><code class="language-bash">(.pyenv)UserName@Your-Computer:Some-folder/DoubleDibz $
</code></pre>

<p>From now ons, any package you install via pip will be installed locally in the <code>.pyenv</code> folder, separate from the global dependencies. Okay, lets go ahead and install what we need for this application.</p>

<pre><code class="language-bash">$ pip install Flask
$ pip freeze &gt; requirements.txt
$ cat requirements.txt
Flask==0.10.1  
Jinja2==2.8  
MarkupSafe==0.23  
Werkzeug==0.10.4  
itsdangerous==0.24  
wsgiref==0.1.2  
</code></pre>

<p>Now we have installed all the necessary dependencies for our application. You can see a list of all the packages and versions installed in the current environment with the command <code>pip freeze</code>. Notice how we save the output to <code>requirements.txt</code>. This allows you or other developers to recreate this same environment to ensure consistency in development and deployment (install dependencies on actual servers).</p>

<pre><code class="language-bash">$ pip install -r requirements.txt
</code></pre>

<p>Remember to exclude the virtualenv (<code>.pyenv</code> or however you named it) from your version control by adding to the ignore list (<code>.gitignore</code> if youre using git).</p>

<h4 id="step1createthefilelayout">Step 1: Create the file layout</h4>

<pre><code class="language-bash">mkdir app  
mkdir app/templates  
mkdir app/static  
mkdir app/frontend  
mkdir app/common  
touch run.py  
touch app/__init__.py  
touch app/config.py  
touch app/app.py  
touch app/extensions.py  
touch app/api/helloworld.py  
touch app/api/__init__.py  
touch app/common/constants.py  
touch app/common/__init__.py  
</code></pre>

<p>Our current structure: </p>

<pre><code class="language-bash">DoubleDibz  
├── app
│   ├── __init__.py
│   ├── api 
│   │   ├── __init__.py
│   │   └── helloworld.py
│   ├── app.py
│   ├── common
│   │   ├── __init__.py
│   │   └── constants.py
│   ├── config.py
│   ├── extensions.py
│   ├── static
│   └── templates
└── run.py
</code></pre>

<h4 id="step2editappapppy">Step 2: Edit <code>app/app.py</code></h4>

<p>Let's start first with the core of the application.  </p>

<pre><code class="language-bash">$ vim app/app.py
</code></pre>

<pre><code class="language-python">import os  
from flask import Flask

import config as Config  
from .common import constants as COMMON_CONSTANTS  
from .api import helloworld

# For import *
__all__ = ['create_app']

DEFAULT_BLUEPRINTS = [  
   helloworld
]

def create_app(config=None, app_name=None, blueprints=None):  
   """Create a Flask app."""

   if app_name is None:
     app_name = Config.DefaultConfig.PROJECT
   if blueprints is None:
     blueprints = DEFAULT_BLUEPRINTS

   app = Flask(app_name, instance_path=COMMON_CONSTANTS.INSTANCE_FOLDER_PATH, instance_relative_config=True)
   configure_app(app, config)
   configure_hook(app)
   configure_blueprints(app, blueprints)
   configure_extensions(app)
   configure_logging(app)
   configure_error_handlers(app)
   return app

def configure_app(app, config=None):  
   """Different ways of configurations."""

   # http://flask.pocoo.org/docs/api/#configuration
   app.config.from_object(Config.DefaultConfig)

   if config:
     app.config.from_object(config)
     return

   # get mode from os environment
   application_mode = os.getenv('APPLICATION_MODE', 'LOCAL')
   app.config.from_object(Config.get_config(application_mode))

def configure_extensions(app):  
   pass

def configure_blueprints(app, blueprints):  
   for blueprint in blueprints:
      app.register_blueprint(blueprint)

def configure_logging(app):  
    pass

def configure_hook(app):  
   @app.before_request
   def before_request():
      pass

def configure_error_handlers(app):  
   # example
   @app.errorhandler(500)
   def server_error_page(error):
      return "ERROR PAGE!"
</code></pre>

<p><code>app/app.py</code> exposes the function <code>create_app</code> which sets up the Flask application with the desired configuration. The file abstracts out the process of configuring the Flask app in multiple stages: </p>

<ul>
<li><code>configure_app</code> : initialize the Flask application with the correct configuration. I setup my application to have 3 modes of configs: local, staging, and producation (see <code>app/config.py</code>). This function will attempt to load the correct mode using either the passed-in <code>config</code> object or by identifying the mode from the environment variable (This is the most flexible for configuring staging and production servers).</li>
<li><code>configure_blueprints</code>: register the given list of Blueprint modules to the application. A common design pattern in Flask is factoring the application into multiple Blueprints modules to greatly simplify the complexity. </li>
<li><code>configure_extensions</code>: initializes Flask extensions for the application. We will see later how we use this function to initialize Flask-WTF, Flask-Script and Flask-SQLAlchemy.</li>
<li><code>configure_logging</code> : configure the way we want to log data. Depending on the environment, we would like to take different approach. For example, when testing locally, you might simply want to log data to stdout console, but for production servers you want to save in some log files.</li>
<li><code>configure_hook</code>: this is a bit less specific. In general, I use it to process requests and responses. For example, I could use it log every incoming requests or measure the time it takes for the server to generate a response for every request.</li>
</ul>

<pre><code class="language-python">def configure_hook(app):  
   // log every incoming requests
   @app.before_request
      def before_request():
         app.logger.debug('Hitting %s' % request.url)
</code></pre>

<ul>
<li><code>configure_error_handlers</code>: Sets up how we want to handle errors. For our purposes, we would return errors in API json format. </li>
</ul>

<h4 id="step3editappconfigpy">Step 3: Edit <code>app/config.py</code></h4>

<pre><code class="language-bash">$ vim app/config.py
</code></pre>

<pre><code class="language-python">import os  
from common.constants import INSTANCE_FOLDER_PATH

class BaseConfig(object):

   PROJECT = "app"

   # Get app root path, also can use flask.root_path.
   PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

   DEBUG = False
   TESTING = False

   ADMINS = ['youremail@yourdomain.com']

   # http://flask.pocoo.org/docs/quickstart/#sessions
   SECRET_KEY = 'secret key'

class DefaultConfig(BaseConfig):

   # Statement for enabling the development environment
   DEBUG = True

   # Secret key for signing cookies
   SECRET_KEY = 'development key'

class LocalConfig(DefaultConfig):  
   # config for local development
   pass

class StagingConfig(DefaultConfig):  
    # config for staging environment
    pass

class ProdConfig(DefaultConfig):  
    # config for production environment
    pass

def get_config(MODE):  
   SWITCH = {
      'LOCAL'     : LocalConfig,
      'STAGING'   : StagingConfig,
      'PRODUCTION': ProdConfig
   }
   return SWITCH[MODE]
</code></pre>

<p>The goal here is to have enough flexibility for different environment. As you can see, we have three configuration mode: <code>LocalConfig</code>, <code>StagingConfig</code>, and <code>ProdConfig</code>. All of which inherit from <code>DefaultConfig</code> which defines a set of standard settings such as project root directory and project name.</p>

<h4 id="step4setupthehelloworldendpoint">Step 4: Setup the <code>helloworld</code> endpoint</h4>

<p>Now you have setup all the basics and the last thing you have to do is creating the API endpoint.</p>

<pre><code class="language-bash">$ vim app/api/helloworld.py
</code></pre>

<pre><code class="language-python">"""
 Simple API endpoint for returning helloworld
"""
from flask import (Blueprint, render_template, current_app, request,  
                   flash, url_for, redirect, session, abort, jsonify, make_response)

helloworld = Blueprint('helloworld', __name__, url_prefix='/api/helloworld')

@helloworld.route('/helloworld', methods=['GET'])
def index():

   data = {
      'message' : "helloworld"
   }      
   return make_response(jsonify(data))
</code></pre>

<h4 id="step5create__init__files">Step 5: Create <code>__init__</code> files</h4>

<p>For each folder we have, we would need to create a <code>__init__.py</code> file to mark the directory as a Python package. <code>__init__.py</code> is usually empty, but it can be used to expose selected portion of the package or rename them to more convenient/more specific names.</p>

<pre><code class="language-bash">$ vim app/__init__.py
from app import create_app  
</code></pre>

<pre><code class="language-bash">$ vim app/api/__init__.py
from .helloworld import helloworld  
</code></pre>

<p>This creates a <code>api</code> package that exposes the different API blueprints that we have without revealing the individual files and the implementation detail. This allows <code>app.py</code> to import the helloworld blueprint from the <code>api/</code> directory level.  </p>

<pre><code class="language-python">// in app.py
from .api import helloworld

// instead of loading from the specific api file
from .api.helloworld import helloworld  
</code></pre>

<h4 id="step6editconstantspy">Step 6: Edit <code>constants.py</code></h4>

<p>The <code>app/common/</code> folder stores constants, functions and objects that are common for every modules we create (hence the name common). For now, we will only need a <code>constants.py</code> file.  </p>

<pre><code class="language-bash">$ vim app/common/constants.py
</code></pre>

<p>Place the following content that defines the directory path for the instance folder. </p>

<pre><code class="language-python">import os

# Instance folder path, make it independent.
INSTANCE_FOLDER_PATH = os.path.join('/tmp', 'instance')  
</code></pre>

<h4 id="step7runandsee">Step 7: Run and see!</h4>

<p>When running the server locally, we'll use <code>run.py</code>  </p>

<pre><code class="language-bash">$ vim run.py
</code></pre>

<p>Place the contents:  </p>

<pre><code class="language-python">import os  
from app import create_app

app = create_app()

if __name__ == '__main__':  
   port = int(os.environ.get("PORT", 5000))
   app.run(host='0.0.0.0', port=port, debug=True)
</code></pre>

<p>Running the file wil create a Flask server running at local port 5000.  </p>

<pre><code class="language-bash">$ python run.py
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
</code></pre>

<p>Now you can hit your browser url : <code>http://localhost:5000/api/helloworld/helloworld</code> to see if the API endpoint is working properly. Alternatively, you can test with curl:</p>

<pre><code class="language-bash">$ curl http://localhost:5000/api/helloworld/helloworld
{
  "message": "helloworld"
}
</code></pre>

<p>Yay, it works! Good job. Now you have successfully setup a basic Flask application with appropriate structure. Now lets get more advanced in the next section where we'll create a user authentication in Flask.</p>]]></content:encoded></item><item><title><![CDATA[Structure a large Flask API backend App]]></title><description><![CDATA[<h3 id="intro">Intro</h3>

<p><a href="https://en.wikipedia.org/wiki/Flask_(web_framework)">Flask</a> is a minimalistic framework that doesn't provide an official way for organizing the application. In this post, I am going to show how we organize our DoubleDibz application directory . Our layout is based on <a href="https://github.com/imwilsonxu/fbone">fbone</a> and there are other useful resources on this subject (<a href="https://github.com/mitsuhiko/flask/wiki/Large-app-how-to">1</a> , <a href="https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications">2</a>). </p>

<p>What makes</p>]]></description><link>http://blog.sampingchuang.com/structure-a-large-flask-api-backend-app/</link><guid isPermaLink="false">f5b67a62-b31e-452e-a0ae-9ac6f1b04003</guid><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Sun, 23 Aug 2015 00:48:00 GMT</pubDate><content:encoded><![CDATA[<h3 id="intro">Intro</h3>

<p><a href="https://en.wikipedia.org/wiki/Flask_(web_framework)">Flask</a> is a minimalistic framework that doesn't provide an official way for organizing the application. In this post, I am going to show how we organize our DoubleDibz application directory . Our layout is based on <a href="https://github.com/imwilsonxu/fbone">fbone</a> and there are other useful resources on this subject (<a href="https://github.com/mitsuhiko/flask/wiki/Large-app-how-to">1</a> , <a href="https://www.digitalocean.com/community/tutorials/how-to-structure-large-flask-applications">2</a>). </p>

<p>What makes DoubleDibz unique is that our backend is purely a API engine that powers the client. This simplifies the complexity in the backend by removing all the logic needed for templating. The backend is only concerned with receiving data, validating data, fetching new data from the db, performing some transformation, and finally returning the result to the client which will decide how to make use of it. If you are interested in creating a fully dynamic web client powered by Flask, read on!</p>

<h3 id="letsgetstarted">Let's get started</h3>

<p>As the <a href="http://flask.pocoo.org/">home page</a> shows, a hello-world Flask application is extremely simple. </p>

<pre><code class="language-python">// run.py
from flask import Flask  
app = Flask(__name__)

@app.route("/")
def hello():  
    return "Hello World!"

if __name__ == "__main__":  
    app.run()
</code></pre>

<p>This code is all nice and dandy but is only appropriate for a trivial application complicated enough to fit in one file. For a large Flask application, we need a more sophisticated structure for the growing complexity. We need to manage more complicated routing for various endpoints, being able to configure under different environments (staging vs. prod), abstracting out common logic, etc. Organizing the application in smaller modules goes a long way. It is like writing clean and modular code: both are simpler to understand and easier for other to maintain and extend.</p>

<h3 id="applicationlayout">Application layout</h3>

<p>our Flask application is based on fbone with some tweaks. The biggest difference here is that the backend only serves as an API layer and has very minimal usage of templating. This is a generic look on our file layout:</p>

<pre><code class="language-bash">├── app
│   ├── __init__.py
│   ├── api      
│   │   ├── __init__.py
│   │   ├── auth.py
│   │   └── ...
│   ├── app.py
│   ├── common
│   │   ├── __init__.py
│   │   ├── constants.py
│   │   ├── helpers.py
│   │   ├── response.py
│   │   └── ...
│   ├── config.py
│   ├── extensions.py
│   ├── frontend
│   │   ├── __init__.py
│   │   └── controllers.py
│   ├── static
│   │   └── ...
│   ├── templates
│   │   ├── app.html
│   │   └── ...
│   └── users
│       ├── UserConstants.py
│       ├── UserForms.py
│       ├── UserHelpers.py
│       ├── UserModels.py
│       └── __init__.py
├── alembic
|   ├── version
│   └── ...
├── tests
│   └── ...
├── fabfile.py
├── manage.py
├── requirements.txt
└── run.py
</code></pre>

<p>This may seem like a complicated mess. Lets take a look and see what each folder (or file) is used for.  </p>

<h4 id="app"><code>app/</code></h4>

<p>First and foremost, all the application logic lives under the <code>app/</code> folder. </p>

<ul>
<li><code>app/app.py</code> is the main entry point of the Flask application.</li>
<li><code>app/config.py</code> will be storing all the module configuration for different environments (local, staging and prod). You don't want to be messing with production data while developing locally! I'll talk more about how to setup different environment in later posts.</li>
<li><code>app/extensions.py</code> contains declaration of all the flask extensions</li>
<li><code>app/static/</code> is the folder from which Flask will serve static files. If you want to use a different folder, see <a href="http://flask.pocoo.org/docs/api/#application-object">here</a></li>
<li><code>app/common/</code> consists of common classes and functions that are useful for all the modules. Some examples are global constants, global helper functions.</li>
<li><code>app/api/</code> contains all the controllers for every API endpoints, such as authentication (login/signup). </li>
<li><code>app/frontend</code>: as opposed to the API folder, the controllers here are serving non API endpoints. For example, it may define entry point to load the HTML file for your fully dynamic javascript application built in backbone, angular, react, or whatever fancy framework you indulge on.</li>
<li><code>app/[module]/</code> represents a functional area in the application, such as users, posts, chat, and search. 
<ul><li><code>app/[module]/[moduleModels]</code> : database models (tables) declaration with <a href="https://pythonhosted.org/Flask-SQLAlchemy/">Flask-SQLAlchemy</a></li>
<li><code>app/[module]/[moduleForms]</code>: WTForm definition in <a href="https://flask-wtf.readthedocs.org/en/latest/">Flask-WTF</a>. Useful for form validation.</li>
<li><code>app/[module]/[moduleConstants]</code> and <code>app/[module]/[moduleHelpers]</code> defines the necessary helper functions and constants for this module.</li></ul></li>
</ul>

<h4 id="andstuffoutsideofapp">And stuff outside of <code>app/</code>?</h4>

<p>The file outside of the application folder shouldn't contain any core business logic for your applications. Those files and scripts are generally for configuring and managing the application. Here I'm listing the scripts and libraries that I use for DoubleDibz.</p>

<ul>
<li><code>requirements.txt</code> contains all the python dependencies for this application. Install using pip. </li>
</ul>

<pre><code class="language-bash">pip install -r requirements.txt`  
</code></pre>

<ul>
<li><code>manage.py</code> contains useful scripts (run, initdb, testing, list routes, etc) using <a href="http://flask-script.readthedocs.org/en/latest/">Flask-Script</a></li>
<li><code>run.py</code> will be used to launch the web server locally.</li>
<li><code>fabfile.py</code>: defining shell operations using <a href="http://www.fabfile.org/">Fabric</a> (which is amazing). You can define command-line scripts for remote deployment (though it's generally not a good practice if you have multiple servers). </li>
<li><code>tests/</code> : how can any application be created without any testing? With <a href="https://pythonhosted.org/Flask-Testing/">Flask-Testing</a>, it is simple to write unit tests for models or  integration tests for the different API endpoints.</li>
<li><code>alembic/</code> : folder containing database migration information for SQLAlchemy using <a href="https://pypi.python.org/pypi/alembic">Alembic</a>.</li>
</ul>

<p>We are organizing the code based on different functional areas. Say you want to build a user authentication system in your new Uber for food website, you would group the <code>models</code>, <code>forms</code>, <code>constants</code>, and <code>helper functions</code> logic under the same folder. This structure makes it very clear that all the files under <code>users/</code> are related for the same purpose. Understanding how authentication and signup works is as easy as browsing the files in this directory. Furthermore, you can expose certain objects and functions from this folder for the consumptions of other modules.</p>

<p>You may have noticed how we add a prefix <code>User-'</code> to the files in the <code>users</code> module, as opposed to simply using <code>models</code> or <code>forms</code> names. This was done deliberately to add more clarity to the meaning of the file just from the file name. Imagine you have a couple different modules, and you open some of the models file in your editor. It is unclear whether a how a <code>models</code> file is different from another <code>models</code> file without examining the code or the file path. We tried our best to set up a naming convention for files, functions and classes in our code in order to provide the most clarity even if it seems cumbersome. </p>

<p>And finally, I mentioned a bunch of Flask extensions and libraries earlier. For clarity sake, this is a list of them:</p>

<ul>
<li><a href="http://flask-script.readthedocs.org/en/latest/">Flask-Script</a></li>
<li><a href="https://pythonhosted.org/Flask-SQLAlchemy/">Flask-SQLAlchemy</a></li>
<li><a href="https://flask-wtf.readthedocs.org/en/latest/">Flask-WTF</a></li>
<li><a href="https://pythonhosted.org/Flask-Testing/">Flask-Testing</a></li>
<li><a href="http://www.fabfile.org/">Fabric</a></li>
<li><a href="https://pypi.python.org/pypi/alembic">Alembic</a></li>
</ul>

<p>Though it's outside the scope of this post, I also want to list a couple other extensions and libraries that made my life so much easier.</p>

<ul>
<li><a href="https://flask-admin.readthedocs.org/en/latest/">Flask-Admin</a></li>
<li><a href="https://flask-login.readthedocs.org/en/latest/">Flask-Login</a></li>
<li><a href="https://pythonhosted.org/Flask-Mail/">Flask-Mail</a></li>
<li><a href="https://pypi.python.org/pypi/redis">redis</a>: in-memory store. Very useful for caching purposes. </li>
<li><a href="http://celery.readthedocs.org/en/latest/getting-started/first-steps-with-celery.html">Celery</a>: setting up async jobs</li>
<li><a href="https://python-pillow.github.io/">Pillow</a>: PIL fork. useful for image manipulation like resizing and cropping.</li>
<li><a href="https://github.com/boto/boto">boto</a>: python interface to Amazon webservice. Useful for uploading files in S3.</li>
<li><a href="https://github.com/pythonforfacebook/facebook-sdk">facebook-sdk</a> : Facebook Platform Python SDK</li>
</ul>

<h4 id="finalnoteonstylingandconsistency">Final note on styling and consistency</h4>

<p>I think one of the most important thing about a code base is consistency. Sometimes, it's more important to be consistent with the rest of the code base than to do what is considered the <a href="http://google-styleguide.googlecode.com/svn/trunk/pyguide.html">right convention</a>. Generally, this is what I follow:</p>

<ul>
<li>2 space indent (no tab)</li>
<li>prefer longer names for the sake of clarity and readability (<code>UserModels</code> over <code>models</code>)</li>
<li>single quotation <code>'string'</code> for string</li>
<li>Naming convention: <code>module_name</code>, <code>ClassName</code>, <code>method_name</code>, <code>function_name</code>, <code>CONSTANT_NAME</code>, <code>local_variable_name</code></li>
</ul>

<p>Of course, I don't always follow my own convention, especially when I'm the only one pushing code. Even so, following some set of rules would guarantee some level of quality and makes it  easier collaborating with others on the same code base. But most importantly, consistency is king. it's better to stick with whatever is already there than creating a hot mess.</p>]]></content:encoded></item><item><title><![CDATA[DoubleDibz Intro]]></title><description><![CDATA[<p><img src="http://blog.sampingchuang.com/content/images/2015/08/general.jpg" alt=""></p>

<h3 id="whydidwecreateddoubledibz">Why did we created DoubleDibz</h3>

<p><a href="http://doubledibz.com">DoubleDibz</a> was our attempt to catch on the trend of the rapidly growing usage of college for-sale groups on Facebook. This was before Facebook introduced the special "<a href="http://techcrunch.com/2015/02/10/facebook-adds-a-new-way-to-sell-items-in-groups/">selling post</a>". At the time, for sale groups were no different from any other groups, where members can</p>]]></description><link>http://blog.sampingchuang.com/doubledibz-intro/</link><guid isPermaLink="false">770c1833-ed41-4a13-bd61-090b3557b8b2</guid><category><![CDATA[DoubleDibz]]></category><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Sun, 09 Aug 2015 00:25:12 GMT</pubDate><content:encoded><![CDATA[<p><img src="http://blog.sampingchuang.com/content/images/2015/08/general.jpg" alt=""></p>

<h3 id="whydidwecreateddoubledibz">Why did we created DoubleDibz</h3>

<p><a href="http://doubledibz.com">DoubleDibz</a> was our attempt to catch on the trend of the rapidly growing usage of college for-sale groups on Facebook. This was before Facebook introduced the special "<a href="http://techcrunch.com/2015/02/10/facebook-adds-a-new-way-to-sell-items-in-groups/">selling post</a>". At the time, for sale groups were no different from any other groups, where members can post and others can comment; yet thousands of students started posting about selling textbooks, electronics, event tickets, used furnitures, and plenty of other types of items. It was extraordinary - more than half of the UCLA students are buying and selling on Facebook. I bet not even this ratio of students use Twitter. </p>

<p><img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-08-at-3-20-38-PM.png" alt=""></p>

<p>As a frequent visitor of the group, I have witnessed the beginning of this trend and how fast it has grown. It's incredible how the market created its own fit on a platform not originally intended for this purpose. In my opinion, besides the fact that everyone already on Facebook and it has the best social features, the biggest driver for the trend is the sense of security and trust instituted in private Facebook groups. Unlike craiglist, here you feel comfortable buying, selling and meeting up with another student from the same school. This makes Facebook well positioned for this market.</p>

<p>At the time, a couple friends (<a href="https://www.linkedin.com/pub/sean-pan/37/905/33">Sean</a> and <a href="https://github.com/JustinWei2010">Justin</a>) and I really wanted to try doing a startup; we were half serious of course. We met once a week brainstorming ideas with the goal of applying to UCLA's summer startup accelerator. The exact plan wasn't very clear as Justin and I both have an internship lined up for the summer. We agreed that if we got in the accelerator we would push back our internship. It was a very thrilling plan. Unfortunately, the idea we came up with at the time didn't make the shot. I guess our pitch wasn't as enticing as we thought. In light of the news, we still decided to continue, and we came up with the idea of DoubleDibz (well, at the time it was called Palxchange).</p>

<p>It made sense. For sale groups are growing like crazy on Facebook, but the tools are basic and there are tons of problems, such as noise, spam, poor search functionality, unintuitive layout for browsing, lack of categories, and this list can go on. So why not build a private social network for buying and selling and we'll address all of these shortcomings Facebook has. The idea really made a lot of sense. Although we didn't think of a good way to monetize besides using the good old ads model but we thought we had a good chance to build our user base by providing a better buying and selling experience than Facebook.</p>

<p>It was a TON of work. Only Justin and I could code and at this early stage neither Sean nor <a href="https://www.linkedin.com/in/claudiawijaya">Claudia</a> (who joined later and helped us with design and advertising strategies) could really help. We knew that a MVP had to be created first before we can start iterating from users' feedbacks. We spent a good month building out the first MVP, which has the essential Facebook features - create selling posts, message sellers, and notifications. The backend was created in <a href="http://flask.pocoo.org/"><em>Flask</em></a> and frontend was fully dynamic and built in <a href="http://backbonejs.org/"><em>Backbone</em></a>. later we also added search functionality and categorization. These were the only screen shots I had from the time:</p>

<p><img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-08-at-4-40-12-PM.png" alt="">
<img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-08-at-4-43-40-PM.png" alt=""></p>

<h3 id="thesupplyanddemand">The supply and demand</h3>

<p>Then we faced the chicken and egg problem. Sure, our product seemed to work fine and have addressed a couple problems we identified from Facebook. But now what? How do we get sellers to come posting when we don't have buyers using it. And why would potential buyers come to our site when nothing is being sold? I suppose we could start by selling random crap that I had in my apartment (it's funny how this was what <a href="https://youtu.be/3OcNdxPhAUk?t=19m5s">Jack Ma</a> did when he first started Taobao). We looked at Airbnb's <a href="https://medium.com/@sanguit/stealing-traction-how-youtube-paypal-stumbleupon-and-airbnb-grew-through-piggybacking-fbced00417e6">growth hack</a> in its early days to solve its supply and demand problem. By piggybacking on Craiglist, Airbnb was able to get a lot of traction really early. This was a no brainer for us. We'll piggyback from existing Facebook for sale groups.</p>

<p>This was why we created a service we called <em>FBsync</em>. Every 10 seconds, it pulls selling posts from different for sale group within the UCLA community (e.g. textbook, housing, clothing, etc) and this allows us to bootstrap from the existing posts on Facebook and present them with better browsing experience. It was our hope to solve the supply problem. In terms of the demand, we started deeper integration with Facebook. For example, if a selling post is created on our platform, we made it very easy to "share" the post back to specific Facebook for sale group. </p>

<p>One of the interesting integrations we experimented with is tagging Facebook friends on our platform, and sending those friends notification on Facebook about the item. Facebook is really good at connecting people, and we noticed a behavior that when you see something that you think your friends would be interested, tagging your friend is a no brainer. This is different from sharing on your friends wall or sending them messages, since this action is low friction and makes tagging multiple people easily. We wanted to replicate this experience on Doubledibz. It was kind of a hack since the link of the notification cannot bring the user offsite, so we had to create a canvas page of DoubleDibz on Facebook for viewing products from tagged notifications. The flow looks something like this:</p>

<p><img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-08-at-5-07-51-PM.png" alt="">
<img src="http://blog.sampingchuang.com/content/images/2015/08/Screen-Shot-2015-08-08-at-5-05-03-PM.png" alt=""></p>

<h3 id="thedawn">The dawn</h3>

<p>We tried to create everything we thought was necessary for a good buyer and seller experience on our platform. However, at the end, we couldn't take over Facebook's popularity. We faced a lot of friction trying to redirect people in joining a new platform. Even though Facebook wasn't intended for online C2C buying and selling, its default social features - private messaging, groups, posts, comments, and likes - already create a very intuitive and natural environment for this market. The last straw was knowing that Facebook is <a href="http://mashable.com/2015/08/05/facebook-online-market-place/">improving for sale groups</a>. And we knew that Facebook groups would only become better, with more tools developed for specific types of collaboration. We finally decided to pull the trigger and call it the end. The convenience of Facebook simply outweighs most if not all the benefit of our standalone platform.</p>

<p>Now that I'm writing this, I feel quite sad. But looking back, it was an amazing experience - to be able to fully dedicate myself on an idea and working closely with Justin, Claudia, and Sean in a team dynamic was a great learning experience. I'm writing to share with you guys all the things that I have learned along the way. Since neither Justin and I had significant backend and frontend experience, we had to learn so much in order to create a website from scratch. What we have learned are likely very useful to anyone who is thinking of creating his or her own website. So here I am. I hope these tutorials could significantly reduce the amount of learning overhead so you can focus on what's really important for your own application.</p>]]></content:encoded></item><item><title><![CDATA[First Post]]></title><description><![CDATA[<p>This is my firs blog post. Ever.</p>

<p>Honestly, I'm not really a writer. Certainly not a clever one. I mean as a programmer, I know how to write beautify code but when it comes to real writing, the most I've ever done was for general education classes back in college.</p>]]></description><link>http://blog.sampingchuang.com/first-post/</link><guid isPermaLink="false">61d41d6f-1daf-4244-b29a-1d36caf50e9f</guid><category><![CDATA[random]]></category><category><![CDATA[thoughts]]></category><dc:creator><![CDATA[Samping Chuang]]></dc:creator><pubDate>Wed, 05 Aug 2015 07:32:06 GMT</pubDate><content:encoded><![CDATA[<p>This is my firs blog post. Ever.</p>

<p>Honestly, I'm not really a writer. Certainly not a clever one. I mean as a programmer, I know how to write beautify code but when it comes to real writing, the most I've ever done was for general education classes back in college. And yeah, it was a joke. </p>

<p>That's why I want to start this blog, somewhere i can practice writing. I'll be writing freely. I would write about the things I think about, things that inspire me (and hopefully that could inspire you), problems I recognize around me, and ideas that I have came up with for those issues. I don't necessarily intend on showing this to the entire world. Though it is public, it feels almost like writing in a diary. Hopefully, many years later, when I look at this post again, I would realize how much I have improved in writing. </p>

<p>Besides practice writing, a big motivation for this blog is to create my own platform for documenting my technical thoughts, ideas and work. This is technically a tech blog. I'm sure you know this unfortunate feeling - how, looking back, so many things you've done or have thought of disappeared in time, leaving no trace and meaning. I want to preserve them, taking snapshots of whatever I have done and I want to share them with anyone whom would potentially find them useful.</p>

<p>Right now, there are already a couple things that come to my mind that I want to write about - my past hackathon projects, freelancing projects, and random hacks that I enjoyed doing. The biggest among them has to be <a href="https://doubledibz.com">DoubleDibz</a>, a social network for connecting buyers and sellers in private communities (Yes, similar to Facebook's for sale groups).</p>

<p>Doubledibz is by far the biggest project that I undertook and I have learned the most from. For the next couple <del>weeks</del> months, I want to write about our technical journey in making this application. I want to share with you guys all the twist and turns, and steps that we have taken to make a semi serious web application. Topics I have in mind include but not limited to <em>server configuration</em>, <em>nginx setup</em>, <em>server scaling</em>, <em>db migration</em>, <em>setting up async batch jobs</em>, and <em>creating a beautifully  dynamic frontend app</em>. I haven't touched the code in almost 8 months (which means I don't remember a thing...), but I intend to go back to the code base and figure out anything valuable that I can leave behind to the community.</p>

<p>Stay tuned.</p>]]></content:encoded></item></channel></rss>