It's your job to move forward

Don't be lazy. Don't wait for your company to give you something new, so you can use the time and advance your skillset. That's shortsighted and won't get you what you want.

I hear a lot of people complain about being stuck doing the same work they always do. "It's hard to move forward," they say. "I need them to give me something different."

Well, it doesn't work like that. People get boxed all the time, like it or not. Somebody has an idea about your skills and will keep using you in that role until the end of time.

I know you are waiting for the magic moment when you get the approval to do something new, challenging, and unexpected. But how anyone would trust you when all you've done is the same boring thing over and over? It becomes a catch 22, and you are the one that can break the cycle.

Nobody cares about where you are in your career as much as you should. Companies care about getting shit done. They care about making money. Taking risks giving people things that may be over their heads is not a brilliant strategy.

Get with yourself and think long and hard about what you want to do. Where do you want to be tomorrow? How do you want to improve your skills? If you are lucky and able to align your interests with your company's, there's a huge opportunity to level up, pitch your new skills to your boss, and get the company to pay for further development.

This strategy works. Waiting for the miracle doesn't.

Deploying TensorFlow Object Detection Models on SageMaker

I know this sounds crazy, but one of the biggest struggles that Machine Learning engineers face is to take their models and make them available so they can be used as intended.

To be a little more specific, taking what seems to work fine in a laptop and deploying it to production so others can take advantage of it seems to be more complicated than what you may believe it should be.

This is something that software engineers have dealt with for decades. There are tools, processes, videos, books, and tricks about how to do it. But deploying machine learning models is comparatively a very young problem, and very likely outside a Data Scientist list of competencies unless they come from an engineering background.

A lot depends on the model you have, so I can't answer all the questions for you, but if you are looking to deploy an Object Detection model using TensorFlow, I can show you a couple of options that will brighten your day.


This GitHub repository has what you need. You can get the code and the instructions on how to run it.

You have two options:

  1. You can deploy your TensorFlow Object Detection model on SageMaker, or
  2. You can deploy on-premises.

The beauty is that you can use the same exact Docker container to do that. One container, two options to get it running.

Random notes, if you are curious

You probably don't need to read any of this to get things up and running, but in case you want a little bit more information, here is some.

Dockerizing this thing makes sure you can deploy your model pretty much anywhere you want. I'm not going to explain what's Docker, but if you are reading this, you probably know already. (And if you don't, cancel your plans for the weekend, grab the popcorn, and solve that problem).

The structure of the files and code inside the Docker container makes SageMaker happy. This container was created to run on SageMaker first, then adapted to run locally (on-premises) as well. I use it both ways. I've never tried it elsewhere, but it is just a Docker container, so it should work as long as you can talk to it through HTTP.

If you go over the documentation, you'll quickly realize that I spent a long time explaining how to set up things on SageMaker (not only the container but how to configure a training job and connect all the pieces to train a model.) You don't need any of this if you are training your model elsewhere, but I wanted to show how to run the entire pipeline on SageMaker.

Finally, at the time of this writing, the TensorFlow Object Detection API doesn't support TensorFlow 2.0. The latest working version of TensorFlow is 1.15, and that's what you'll get on the GitHub repository. I'm pretty sure I'll update it as soon as 2.0 is supported, but for now, that's the best we get.

Moving the blog to Python 3

Python 2 is out of support. I created this blog back in 2014, using Python 2 running on Google's App Engine Standard Environment. It worked great. It gave me zero problems during these 5+ years.

But it was time to extend its life for another 5+ years, so I updated the code to run in Python 3.7. And made a bunch of improvements while at it.

The most significant change was to simplify the architecture of the blog and the processing of pages. Back then, I did a lot of cool stuff to make sure the blog was fast. And it was fast! But I'm not sure that it was faster than a version without all that.

In theory, everything I did in 2014 makes sense. Hell, I might have to go back to a similar version in two weeks if I realize that this new engine doesn't cut it! But I don't think I'll need it.

It's a shame because I spent so many hours optimizing the blog. Premature optimization. I should have known better.

Anyway, I hope everything stays working as it's been. I'll keep an eye on it to make sure everything is okay. Then, I'll go back and clean every file related to the old version.

Let's see how it goes.

Running a Python FastAPI application in App Engine

If you haven't checked FastAPI as an alternative to Flask, take a look at it, and you'll be pleasantly surprised by how capable, modern, and cool it is.

I'm not going to talk about FastAPI here, but I'll explain how to get a simple "Hello World" application running on Google's App Engine.

For this example, I'm going to be using the App Engine's Python 3 Standard Environment. Deploying to the Flexible Environment should be very similar.

You'll need to create three files:

requirements.txt - Here, you'll list your required libraries so App Engine can prepare the environment to run your application. Here's what's needed for this file:


Whether or not you specify the versions of each libraries (e.x. gunicorn==20.0.4) is not relevant now. Either way works.

Then you need an app.yaml file - This is the configuration of your application. Here we need to specify the runtime we are going to be using, and the entry point for App Engine to provision a new instance:

runtime: python37
entrypoint: gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker

The uvicorn worker is the one that will allow us to run a FastAPI application. Also, notice I'm specifying that 4 workers (-w 4) should be serving the app. This number of workers should match the instance size of your App Engine deployment, as explained in Entrypoint best practices.

Finally, we need a file containing a FastAPI object called app:

from fastapi import FastAPI

app = FastAPI()

async def index():
    return "Hello World!"

To deploy the application, and assuming you have the Cloud SDK installed and initialized; you can run the following command:

gcloud app deploy app.yaml

This command should deploy the application to App Engine. From there, you can visit the URL configured for your project, and you should get the "Hello World!" text back.

You need both learning and doing

Great developers spend much of their time writing code. It’s not only about how much they study, read, and keep up with the latest trends but how much time they dedicate to hone their craft. They constantly make things. Again and again.

Great developers spend much of their time reading to improve what they already know. It’s not only about writing code day in and day out, but about keeping up with what’s new to stay relevant. They continually augment their knowledge.

I’ve seen people that can’t make anything useful, but they are always on top of what’s new. I’ve seen people stuck in the past, but are excellent building things with what they know. They both have a place. They are both in the middle of the pack.

To be a great developer, you need as much learning as doing. Every day is another opportunity for you to aim higher.

Naming things

I've written before about code clarity, but I don't think I paid enough care to the importance of naming things.

For the most part, we are sloppy and tend to minimize doing things that don't seem to be worth in the short term; we have natural incompetence to comprehend the long term implications of our actions. This reflects throughout our lives, including when we write code.

You can see the reflection of this in multiple different ways, but the one that brings me here is while naming things (variables, classes, functions, etc.)

Some people make an extra effort in being brief and cut their typing as much as possible. Here is when you find "vlcty" instead of "velocity" or "prc" instead of "process." Other people have a knack for finding the most obscure names possible, that although verbose, mean nothing after five minutes of typing them.

Unfortunately, whatever time they think they are saving by not taking the necessary care today, they will pay back later in brain cycles deciphering their code.

Writing code should be like writing a novel. Sure, being concise is a useful attribute, but most important is being clear. I understand that moving fast is excellent, but it can't come at the expense of clarity.

When reading your code, the intent should be obvious. It is not enough that you know what the code is doing: things should be transparent enough to provide answers to even the most casual reader.

This is a hard trait to develop. This is something that separates good from great developers.

Product Stages

When working on a product, it is good to have an understanding of what each stage of completion means. For different teams, these concepts will vary, but this is the way I like to do it:

  • A development version is a messy thing. You shouldn't expect much from it, and you should be ready for the application to blow up at any time without notice. We never deploy an application at this stage.

  • A beta version is stable, and as far as developers are concerned, it's bug-free. Of course, at this stage, the product needs much more testing, but you should be able to use it without too many issues popping up. You should never deploy a beta version for an audience wider than your beta group (definitely not to your production customers!)

  • A stable version (or final version) is good to go on production, and there are no major known bugs. Ideally, there aren't any bugs, but depending on what you are building, this might not be a reasonable goal. You should feel proud of getting to this point.

You might have a different definition for each stage of your product, but what's important is that your whole team understand what's involved in reaching each one of them.

By the way, trying to keep bug-free versions of your product could be extremely hard, and I've had to relax that constrain before because of multiple factors (time and money being high on that list.) Nevertheless, I always try to squeeze that bug list down as much as I can; there's nothing like feeling proud about the work you do.


One of the biggest complaints about the Scrum's daily standup meeting is that, more often than not, they become "status" meetings.

Complain about this to any die-hard Scrum fan, and they will quickly tell you something along these lines:

You are doing it wrong. You need to make sure your team is using this time to optimize collaboration and performance, improve communication, identify impediments, and improve the team's level of knowledge on the product.

The lecture will serve you well for a while, but for the last ten years, our standup meetings have degraded to status meetings shortly after. All. The. Time. Every. Time.

I work with smart people, and over the years, we've had a dozen or so specialists whose only job have been making sure our Scrum process is top-notch. We are proud of what we've accomplished, but the standup meeting seems to always be the same boring, useless crap.

Here is a crazy idea: maybe the problem is not our people, and we aren't doing it wrong. Aren't ten years, dozen of teams, and hundreds of projects enough to prove that the standard by-the-book Scrum standup meeting is not going to work for us?

I feel we have given them a fair chance.

Slow and steady

We made a lot of progress in our product over the last two weeks. It was a bunch of work, and it took nights and part of the weekend to get where we are right now.

I love the progress, but I hate what we had to do to get there.

The speed we showed is not sustainable. We can clap all we want but after a couple more weeks working like this everyone will be burned out and unwilling to move. This is not a great way to build a product. We are supposed to be running a marathon, not a sprint.

(Funny that Scrum uses the term “sprint” to refer to each iteration. I get why, but I don’t like the implication of speed wrapped in that term.)

We are scaling back the effort a little bit. Not sandbagging, but trying to be a little bit more realistic about what we can do with 80 hours of work.

I’d instead do slow and steady. We are playing the long game here, and my job is to make sure we get there as keen and excited as we started.

The stale backlog

Backlogs become stale quick.

As soon as some of the stuff reported in the backlog stops being relevant, the whole thing becomes useless and distracting.

I just removed 27 irrelevant entries from the backlog of a project I'm working on. There were 27 things reported in there.

I bet you a lunch that if you go to your backlog right now, you'll also find tons of stuff that doesn't make sense anymore. The amount of cycles your team spends every week sifting through stale requests is wasteful and completely unnecessary.

This is why I like to get rid of backlogs. Completely.

Instead, I keep a high-level plan for the next 4 - 6 weeks. If a feature or idea is not ready to be scheduled for that timeline, I ignore it. Important things will find a way to surface again and again, and as soon as there's enough clarity around it and we are ready to tackle it, I'll add it to the schedule.

This helps my team stay focused on what's important. It keeps them away from having to fish what's relevant from an ocean of dead requests.

The fear is always the same: you think you'll forget what's essential, therefore you need to add it to a list somewhere. I've found that this is the least of your problems when developing software. Forgetting is a good thing: it means that you didn't spend time doing something that wasn't important enough.