Thursday, December 24, 2015

Using Decorators to Validate Flask Views

Flask is an awesome micro-framework and a great way of handling http requests when creating web apis.  What I'm proposing here is that custom Python decorators can make development of such projects even better.

Consider, for example, the http requests that post of json data.

What do we have here?  The model is an interface to the database.  It sends an exercise id and score to be persisted to it.  However, the get method calls on those json dictionaries can and will return None if there is no matching key.  Consequently, there is the potential for empty values to be inserted into the database.  We don't want that.  What to do then?

Validating Without A Decorator

One option is to look to make sure the keys are there and abort the api call with a 400 error.  Since status code 400 signals a bad request, the client will find out that the request bombed because they submitted the request incorrectly.  That would look something like this.

Validating With A So-So Decorator

The validation in the example above can be a little distracting.  Code is read more than written.  Extra safeguards are wise but also kind of distracts from the main point of what the function is ultimately trying to do.  So let's try a simple decorator and offload validation to there.

Not bad.  The only thing to bear in mind is that decorators are being chained together in this context.  The top decorator decorates the function that results from the decorators below it.  Flask is a framework.  We want it to register the final result of our customization with minimum confusion for all parties concerned.  For that reason, you generally want put the Flask routing decorator on top.

Generating Decorators

We're not done yet.  What about the other Flask functions dealing with json data?  Do ALL the json requests passed in to other functions use the exact same keys?  If not, the decorator we made so far won't work on those functions. We could create separate decorators specific to the keys of each function's json arguments.  Unfortunately,we'd end up with the very code repetition we've been trying to avoid.  What to do then?

One solution would be to write code to automate the creation of decorators that fit each target function's validation needs.  So what we need is something that creates other decorators.  When we do that, the end result is a decorator that takes arguments.  Here's what that looks like.

Not bad!  Not bad at all.  Accepting a variable length argument list allows us to put in as many string arguments as needed for the keys that need checking.  Those arguments strings are used to create a custom decorator on the fly.  That newly created decorator wraps the function we're targeting.  As a result, we now have a special kind of decorator that can be used to validate any json data at all.  Just specify the names of the keys and you're golden.

More Resources

There's a lot about decorators that hasn't been covered in this blog post.  Here are some other angles on what I've written about here.

Thursday, October 15, 2015

A Simple Full Stack Chat Application That You Can Try Out

Simplechat is a basic chat room application put up on Github over the past week.  It does only the basics.  You sign up for an account.  You log in.  You chat at the chat screen.  You close your browser window when you want to log out.  

Here's Your Login Screen

What It Looks Like to Create An Account

What the Chat Room Display Looks Like

The core to setting it up is super easy provided you have the tools setup.  Check out the sites for Git, Vagrant, Virtual Box, and Ngrok to get what you need if you don't already have it.
  1. git clone
  2. Secure it. (see the readme for details )
  3. cd simplechat
  4. vagrant up
  5. ngrok 80
And that's it.  It's a single developer full stack project done in five days.  There's a lot to learn from this.  There's systems administration with  Ubuntu Linux and MySQL.  There's Front end development with AngularJS and Bootstrap.  Last but not least, there's server scripting in Python Flask, and SQL Alchemy.   

Play with it.  Tweak it.  Pick it apart.  Have fun!

Thursday, March 26, 2015

5 Lessons Learned From the 30 Day Github Challenge

Today, I completed my 30 day Github challenge.  That challenge was inspired by others who came before me.  It was an adventure that took me through web applications and other scripts.  It was a worthwhile experience.  Here are my takeaways.

1.  You get a lot done
Even if any one day doesn't feel like a big accomplishment, it's pretty cool to look back and see what those little steps added up to.  Seeing progress on 9 different projects feels good.

2.  You appreciate the mundane
Commits focused on boring things like code cleanup, docs, and tests matter.  They shine a light on what's good or not-so-good about your project.  I uncovered bugs that might have otherwise not been spotted.  Some good dumb refactoring was also a great way to get commits in on those not-feeling-so-smart days.

3.  Your learning is project-oriented
This challenge encourages focus on projects.  There are some things that are best learned in that context.  The practical challenges of getting Flask and Angular to work together is one example that comes to mind.

4.  Life challenges your ambition
Life has a way of running interference on projects that require any sort of commitment.  Expect it and keep your daily ambitions small to take it into account.  I've grappled with a move to a new place and illness among other things during the past month.  Having tiny goals was a lifesaver for me.

5.  You get reacquainted with old code
Revisiting old projects is a great way to get commits in.  It gives you perspective to how you've come along as a programmer.  My final commit for this challenge was a 4-year-old addon I wrote for Blender.  In a way, it feels like reconnecting with old friends.

Take up this 30 day challenge.  It's satisfying, fun, and challenging.  You'll grow as a developer having done it.

Sunday, March 1, 2015

Basics of Working with Git

Git is an empowering version control tool.  Everyone gets a copy of the repository.  You get freedom to experiment and take chances.  That wiggle room is helpful when working on your creation.

If you haven't yet, go install it.  Here's a link for getting a good setup for Windows. 

Setting Up Your Project

Fire up GitBash.  This gives you a Linux-like environment to work with.  Linux expertise is not needed to follow along.

To keep things simple, make a folder and initialize it.  Here's what to do....

mkdir myproject

cd myproject

username@YOURCOMPUTER ~/myproject
$ git init
Initialized empty Git repository in c:/Users/username/myproject/.git/

username@YOURCOMPUTER ~/myproject (master)

The git init command sets up your initial repository.  That repository keeps track of file changes.  A special folder called .git handles the magic of managing those changes.  You need not understand the contents of that folder.

We need a file for git to keep track of.  Make a file called hello.txt.  Put some text in it.  Something like below should do for an example...

hello there, how are you?

With that set up, you now have what you need to learn the basics of how git works.  The working directory has the current copy of the files you're working on.  Hello.txt lives there right now.  

Setting Up To Commit

You should always know the state of your project before committing things to Git.  Here's how you do that...

username@YOURCOMPUTER ~/myproject (master)
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add ..." to include in what will be committed)


nothing added to commit but untracked files present (use "git add" to track)

username@YOURCOMPUTER ~/myproject (master)

Git status tells you the state of your project.  Note the "Untracked files" section.  Those are the files that are currently not being managed by Git right now.  We want hello.txt under Git management so do the following... 

username@YOURCOMPUTER ~/myproject (master)
$ git add hello.txt

Check the new state of things by running git status again...

username@YOURCOMPUTER ~/myproject (master)
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

        new file:   hello.txt

username@YOURCOMPUTER ~/myproject (master)

Note that hello.txt file is now under "Changes to be committed".  That's because we did a git add on that file.  That command put hello.txt in a place called a staging area.  That area holds a snapshot of the file changes about to be committed to the repository.

Commits and Commit Logs

Let's add our first item to that repository by doing a commit....

username@YOURCOMPUTER ~/myproject (master)
$ git commit -m "my first commit"
[master (root-commit) bbbc1cf] my first commit
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

username@YOURCOMPUTER ~/myproject (master)

The git commit command sends a snapshot of changes that you staged into the repository.  The repository is a collection of those snapshots complete with information about the changes associated with them.  

Congratulation!  You succeeded in making your first commit to a git repository.  To confirm, check the commit history with the git log command.

username@YOURCOMPUTER ~/myproject (master)
$ git log
commit bbbc1cf06977dd40780430a5665f94f083e2bc98
Author: you
Date:   Sat Feb 28 15:38:47 2015 -0500

    my first commit

username@YOURCOMPUTER ~/myproject (master)


And so there you have it.  What we've learned so far.....

  1. We know that we can create a repos with git init.
  2. We know that you can take individual files and set up their changes to be saved using git add.
  3. We know how git commit takes the staged changes of our files and sends them to a saved collection of changes called the repository.
  4. We understand the difference between working directories, staging, and the repository.  The working directory holds the current files being edited.  Staging holds a snapshot ready to commit.  The repository holds a collection of those snapshots.

That should cover the bare basics of git to begin with.  Was this a helpful intro?  Let me know in the comments.