Posts

Increase Your App Adoption

At Oak City Labs we develop using a particular stack of technologies we are not only comfortable with, but believe to be the most effective tools in solving whatever challenges come our way. Too often when a developer says “We use X framework or Y library”, it sounds like utter gibberish and has no real meaning to non-technical people. This disconnect is the inspiration for my blog series: Non Technical Overviews of Technical Things.

In this post, I will cover Flask, the web framework we use. You can think of a web framework as a set of building blocks that developers use to write a web application. It’s important to note that in this article when I say “web framework,” I’m talking about a web server framework. In other words, Flask lives on a server in the cloud rather than running on a user’s computer. Flask is an “unopinionated micro web framework” written in Python.

Let’s break that down:

Micro

Why “micro”? Because instead of being an all-in-one swiss army knife style solution, Flask is an add-as-you-go barebones solution from the start. This low barrier to entry allows developers who want to build a small program or a quick prototype to just download and get going with a few simple lines of code. According to the Flask docs, “The ‘micro’ in microframework means Flask aims to keep the core simple but extensible.”

Unopinionated

Why “unopinionated”? Again, the Flask docs explain it best, “Flask won’t make many decisions for you, such as what database to use. Those decisions that it does make … are easy to change. Everything else is up to you, so that Flask can be everything you need and nothing you don’t.”

Web Framework

A web application could be anything from a website to a mobile app to an online document editor to an email program. In programming, a framework is a tool that aims to prevent developers from having to rewrite code each time they want to accomplish a task. Thus, web frameworks fill the role of facilitator and middleman by allowing developers to quickly create web services, resources and APIs that people can interact with through user-facing programs like web browsers and mobile apps.

Okay, that’s cool and all, but what does a web framework mean to me, an average user?

A lot of tasks in web development are very repetitive. One example is as simple as a user visiting a webpage. Let’s use Google as our example. Let’s say you open up your favorite web browser, type “Google.com” and hit enter. You see something like this:

In this scenario, the web browser is in charge of:

  • Displaying what you see, from the search box to the Google logo
  • Allowing you to interact with the page

And the web framework is in charge of:

  • Providing your web browser the code for the page, the images, and any scripts that run on the page.
  • Performing any searches you enter
  • Logging you into your Google account and ensuring you stay logged in

Why do we use Flask?

As a services company, we often begin working with clients by building small prototypes to test the viability of certain ideas for them. As such, we have found that choosing tools that allow us to easily and quickly build prototypes for potential long-term projects is essential to success.

Extensibility

In the software world, prototypes are often scrapped once a project is given the green light. With Flask, we can quickly build up a prototype and just as easily build on top of it as we go. Think of Flask as a kit of legos where the main building block has nodes on every side to be built on top of. You can customize it any way you want, work with other technologies any way you want, and it doesn’t tell you that you should do anything a certain way.

Durability

While Flask is small in size, it is developed in a way that allows it to scale incredibly well. The Flask docs have an entire chapter on “becoming big.” Even Pinterest uses Flask for their API! For CurEat, we built the original prototype using Flask, and now in release, with thousands of users and about a dozen pieces of technology all working together, Flask is still working like a well-oiled machine, showing no signs of slowing down.

Additionally, the small overall size of Flask means there are less places for security vulnerabilities to occur. If there ever were to be a vulnerability in the code discovered, Flask’s large, active open source community would handle it swiftly and promptly release an update.

Here’s a Quora post showing some large web applications that use Flask.

Python

We really like Python. It is a well-documented and incredibly popular programming language being used increasingly for web server development due to its modularity and ease of use. The other popular web server programming languages are PHP, Ruby, and Java. PHP and Java show their age and are well known for not being quick prototyping languages. Sinatra is the Ruby equivalent to Flask. We find Python to be an easier programming language to work with overall, and more developers are familiar with it, so there is typically more out there in terms of 3rd party libraries and documentation.

Flexibility

This is perhaps the most important point of all. As an app development shop, we have to always be ready to adapt to rapidly changing requirements. Flask allows us to easily change direction without having to backtrack and lose valuable time. Flask also allows us to change the type of tools we use alongside it without having to change the logic itself. For instance, we could go from using a simple file for data storage during prototyping to a fully redundant PostgresSQL database in production without any change in logic. This ability to change at a moment’s notice is very helpful when we are deciding how we want to structure a project.

Recap

  • Flask is a web server framework, which is a crucial piece of any app or website that uses the internet.
  • Flask helps us manage all the different pieces that go into creating our mobile and web apps.
  • We like Flask because it is small, flexible, durable, and allows for easy prototyping.

This was the first part of a series of non-technical overviews of technical things. Stay tuned for more!

Since joining the team at Oak City Labs last year, I have had many conversations with friends, family and prospective clients about mobile app development. When I show them an app we’ve built, like CurEat, they often tell me that it looks great, and then ask me to show them which parts of the app I made. While seemingly an innocuous comment intended to allow me to showcase my hard work and reap some easy praise, this particular request typically leads me to release one of my patented <heavy sighs>.

But Cory, why do you heavy sigh at such a polite, ego-boosting request, you ask? Well, fellow human, I release the air from my lungs at a much faster rate than usual in an exasperated manner because users of our apps don’t actually see anything I have made. They see the work of the design team in the visuals of the app. They see the buttons, lists, login screens and settings menus that Jay (iOS) and Taylor (Android) have coded in. They even see the legalese a lawyer somewhere put together. So when I tell people that I spent over a year working on an app after explaining that there is no visual evidence of my work at all, they get this sort of half-confused, half-amused look on their face.

Of course, I could simply tell people that I am a backend developer who helped make the Python Flask server, PostgreSQL database structure, RESTful API and Angular webapp that allow the mobile app to be more than a sad, functionless, empty shell. This jargon only helps those with a technical background, and usually leads most others to say something along the lines of “Oh, OK…” when in reality, they’re thinking “Was he even speaking English?”

And so, through a long, arduous process of trial, error, confused looks and copious amounts of feedback, I have concocted what I believe to be the ultimate formula in explaining what my actual role is in the app development process.

To aid in understanding my role as a behind-the-scenes magician, I will refer to the Snapchat app as an example.

For those who aren’t familiar with Snapchat, let’s run through a typical Snapchat use case. This is assuming you already have an account and are logged in.

Step 2: Snap a super artsy picture of your keyboard and wrist rest

Step 3: Send it to your friends (Some names below may or may not be based on the many nicknames of Burton Guster)

Aaand we’re done! I have now sent a poignant photo of my keyboard to two of my closest imaginary friends. Soon, they will receive a notification of the photo and will be able to open and view it for themselves.

This is the process for using the app, but to understand how we are able to get to this point and do such a thing, we need to step back to the very beginning.

Here is the terminology I will use in the following examples:

  • Mobile Developer – Somebody who builds the actual app that a user sees on their mobile device
  • Backend Developer – Someone (like myself) who works on the behind-the-scenes details such as the server, API and web framework. If this doesn’t make sense, that’s OK – we’ll get there!
  • Snap – A snap is an image that you exchange with friends on Snapchat

When the app loads, you have the option to log in or sign up. So far, this is all the work of the mobile developer. They created this screen, pulled in images from the designer, added some text onto buttons, and bam. This screen is born:

Now let’s say you click Log In. You are then taken to this screen:

This screen lets you log in with your account information and takes you into the part of the app where you can actually send and receive snaps. Every “usable” thing on this screen was added by a mobile developer: the input areas for username and password, the “Forgot your password?” link and the “Log In” button. So far, the backend developer hasn’t played a role in either of the previous screens.

Now, what happens when you press the “Log In” button? Does the phone magically know whether your account info is valid or not? If that information were only stored on your phone, how would you be able to log into Snapchat on a new phone with the same account?

The answer: You wouldn’t. Your account information is not even touched by the mobile developers!

*My Time to Shine!*

There are a lot of behind the scenes details happening here that the backend developer is responsible for, so let’s break down the differences between the work of the mobile and backend developers in the above scenario.

Technical Breakdown:

  • Mobile Developer:

    • Create app screen with inputs
    • Send username/password to server
    • Receive output from server telling the app if the login was successful
    • Continue on to the next app screen if the user logged in successfully
  • Backend Developer:

    • Tell server how to handle a request to log in a user
    • Tell server how to check with the database to confirm/deny a login request
    • Tell server how to send a request back to the app if the user logged in

Non-Technical Breakdown:

The mobile developer creates the code for the login screen, the backend developer creates the code for all of the actual “logging in” and checking of whether you are a valid user or not.

Let’s go back to the scenario of sending a snap to your friends.

Starting with my super duper artsy photo again, we can examine this screen. All the interactions on this screen are completely up to the mobile developer. A few examples are the ability to save this image or add text to it. Now, let’s say the user clicks the button in the bottom right to choose which of their friends to send the snap to.

We’re taken to this screen. The app displays a list of names which are all of the potential friends you could send your snap to. You select the ones you want, then click the send arrow in the bottom right to send your snap to these friends. Everything visible is presented with code from the mobile developer still. Except…

Let’s back it up.

Where did your friends list come from? Does your phone just magically know which of your friends have snapchat and also have you as a friend? How would you add or remove a friend? And what are those numbers and emojis next to the stars on the right side of each name row?

That’s a lot of questions, so let’s do a breakdown like we did before.

Technical Breakdown:

  • Mobile Developer:

    • Request list of friends and friend information from server
    • Display list of friends
    • Display information about each friend (such as the numbers and emojis)
    • Allow the user to select which friends will receive their snap
    • Tell the server who the user wanted to receive their snap
  • Backend Developer:

    • Build a list of friends and friend information for the given user and return the information to the app
    • Perform the actual sending of the snap to all of the selected friends.
    • Notify all the friends that they have a new snap

Non-Technical Breakdown:

The mobile developer creates the code that displays all the friends and let’s the user choose who to send the snap to, but the backend developer creates the code that tells the app who the user’s friends are and the code that actually sends the snap to those friends.

At the end of the day, there’s a lot of communication that needs to happen between mobile and backend developers, because as you can see, they depend on each other very much. Without a mobile developer, all the backend logic and data and snap sending would be pointless. Similarly, without a backend developer, Snapchat wouldn’t actually be able to do anything. It might sit there looking pretty but you wouldn’t be able to send your snaps to anybody, which would be quite sad.

I hope my examples helped, but if not, here are a few analogies to provide more clarity:

Non-Technical Analogies:

  • A mobile developer is like a news anchor. Without the backend developer (teleprompter), the news anchor would just sit there looking pretty without knowing what news to tell viewers about.
  • Alternatively, think of a mobile developer like a grocery store, choosing how to display all of the food that the backend developer delivers. Without the shelves and organization from the mobile developer, all of the food from the backend developer would be too chaotic and unstructured to give to the shoppers. But, without the backend developer, there would be no food at all to give to the shoppers.

Technical Analogies:

  • A mobile developer creates your Gmail app, but without the backend developer, your email would never show up in the app.
  • A mobile (or web, in this case) developer would create the Netflix app or website, but without the backend developer, no shows would show up or be watchable.

When I think about automation, the first thing that pops into my head is a giant warehouse teeming with robots that scurry around, filling orders and shipping them off to fulfill the whims of internet shoppers. Something like this:

It’s not exactly the Jetson’s yet, but they’re getting there. And robots are cool.

But automation really applies to anything that can save us time, reduce errors and make us more efficient (which is code for saving money). The best targets for automation are tasks that are well defined, repetitive and common. In other words, chores that are boring, tedious and error prone. Fortunately for developers, we have plenty of these targets.

Our primary goal here is to automate the journey from code repository to finished product. A developer should be able to check code into the git repo and the system will build an installable product with no human intervention.

Benefits of Automation — Fast, Consistent, Correct

Let’s look more specifically at what automation can do for developers. At Oak City Labs, we build mobile apps and their backend servers that live in The Cloud. What sort of concrete things do we get from automation? We’re able to save time, ensure dependability and have confidence in every build. Automation creates builds that are fast, consistent and correct.

Saving time is the most obvious benefit of the whole process. When I have a bug to fix, I track it down and fix the errors on my laptop. Once I check that fix into git, I’m done. The automation kicks in, notices the change, runs through the build process and uploads the fixed app to a beta distribution service. Our QA folks get an email that the new app is ready to install and test. That whole process takes 30 minutes, but I’m free and clear as soon as I check into git. That’s 30 minutes of waiting for builds, running tests, and waiting for uploads that I don’t have to worry about or monitor. I’m on to tracking down the next bug. Saving half an hour a couple of times a week adds up, and sometimes it’s more like a couple of times a day. With those extra hours, I can fix more bugs and write more tests!

Less obvious than the time savings is consistency. Automation is codified process, so these builds happen exactly the same way each time. The automation always takes the same steps, in the same order, in the same context every time. Doing builds manually, I might use my laptop or my desktop, which are mostly the same, but not quite. Because I’m in a hurry, I might forget one of those simple steps, like tagging the repo with the build number, which won’t matter until I try to backtrack a buggy build later. With automation, we just don’t have those worries. Even better, I can go on vacation. Any of the developers on our team can build the app correctly. If the client needs a trivial fix, like changing a copyright date, it’s simple. Anyone on the team can update the text in the code repository and a few minutes later, a build is ready to test. Not only does the automation reduce the chances of human error, but it makes sure we no longer have to rely on a particular human to operate the controls.

Along with consistency, we also have confidence in every build. Consistency builds confidence, but so does testing and regimen. We build our software with a healthy dose of testing. As part of our automated builds, the testing ensures that the code behaves as we expect and that a change in one part of the code hasn’t inadvertently caused an error elsewhere. Of course we don’t catch every bug, but when there is a bug, we add a test to make sure we don’t make that mistake again.

Our automation is a tool we use every day as part of our development habits. It’s not a special task that’s only run at the full moon to bless our new release. It’s our daily driver, that reliable Toyota Camry we drive every day that always runs. It might need a little maintenance now and then, but it’s not your crazy uncle’s antique Mustang that only works a third of the time when he tries to take it out on a Saturday afternoon. This is really important when crisis mode comes around. Imagine if the app has some critical bug that needs to be patched ASAP. Because we have confidence in our consistent and correct automation, we can focus on fixing the bug and know that once it’s fixed, releasing the new version to users will be a smooth standard procedure.

Automation has been something we’ve grown to rely on in our development process because it make us more efficient and saves us time. For our clients, saving time means saving them money. We can get more work done because we can focus on the real challenge of writing apps and leave the boring tedium to our trusted automation. With the consistency and confidence that automation adds to our workflow, we can always be proud to deliver a top notch product to our clients. Fast, consistent and correct — automation delivers all three!

How the Magic Happens

So… automation is great and wonderful and makes the grass greener and the sun shine brighter, but how does it work? We’ve been talking in very vague terms so far, so let’s get down to the bits and bytes of how to put it all together.

For the last several years, we’ve been using a git branching strategy based on the excellent git-flow model. You can read all the brilliant details in the link, but the short story is that you have two long lived branches, master and dev. The master branch contains production level code that is always ready to release. The dev branch is the main development version that gets new features and maintenance fixes. Once a new feature set is ready in dev, it gets merged into master. This maps very nicely onto our concrete goals for automation.

Our projects have two deployment modes: beta and production. Beta is code from the dev branch. This is code ready for internal testing. For mobile apps, beta builds are distributed to QA devices for testing against the staging server. For server apps, beta builds are deployed to the staging server for testing before rolling out to production. Production mode is the real deal. Production mobile apps go to the app stores and to real users. Production server apps are rolled out to public servers ready to support users.

The automation workflow maps from git-flow into our deployment environments with the dev branch always feeding the beta environment and the master branch feeding the production environment.

The engine we use for our automation is a continuous integration server called TeamCity from JetBrains. It’s a commercial product, but it’s free for small installations. TeamCity coordinates the automation workflow by

  1. monitoring both master and dev branches in git
  2. downloading new code
  3. building the new version of the app
  4. running all the tests
  5. deploying to beta or production

If any of those steps fail, the process stops and the alarms go off. Our dev team is alerted via email and Slack and we’re on the problem like minions on a banana.

The last three steps are specific to the product type. For iOS, we use the wonderful Fastlane tools to orchestrate building the app, running tests, and uploading to either Fabric’s Crashlytics beta distribution service or to Apple’s App Store for production release.

We use Fastlane for Android, as well, so the flow is very similar. Beta releases go to Crashlytics, but production releases are shipped to the Google Play Store.

Our servers are written in Python and our web applications are in Angular. Testing for both uses the respective native testing tools, driven from TeamCity. For deployment, we use Ansible to push new versions to our beta and production clusters. We love Ansible because it’s simple and only requires an ssh connection to a node for complete management. Also, since Ansible is Python, it’s easy to extend when we need to do something special.

Since all of our build paths go through TeamCity, the TC dashboard is a great place to get a quick rundown of the build status across all projects.

With TeamCity coordinating our workflow automation and using tools like Ansible and Fastlane to enable builds and deployments, we’ve been able to build a system that is fast, consistent and correct, relieving us of the tedium of builds and letting us focus on the hard problems of building great apps for ourselves and our awesome clients.