Categories
Python

Getting Started with Pipenv

If you’re a Python developer, you probably know about pip and the different environment management solutions like virtualenv or venv. The pip tool is currently the standard way to install a Python package. Virtualenv has been a popular way of isolating Python environments for a long time. Pipenv combines the very best of these tools and brings us the one true way to install packages while keeping the dependencies from each project isolated. It claims to have brought the very best from all other packaging worlds (the package manager for other languages / runtimes / frameworks) to the Python world. From what I have seen so far, that claim is quite valid. And it does support Windows pretty well too.

How does Pipenv work?

Pipenv works by creating and managing a virtualenv and a Pipfile for your project. When we install / remove Python packages, the changes are reflected in the Pipfile. It also generates a lock file named Pipfile.lock which is used to lock the version of dependencies and help us produce deterministic builds when needed. In a typical virtualenv setup, we usually create and manage the virtualenv ourselves. Then we activate the environment and pip just installs / uninstalls from that particular virtual environment. Packages like virtualenvwrapper helps us easily create and activate virtualenv with some of it’s handy features. But pipenv takes things further by automating a large part of that. The Pipfile would also make more sense if you have used other packaging systems like Composer, npm, bundler etc.

Getting Started

We need to start by installing pipenv globally. We can install it using pip from PyPi:

Now let’s switch to our project directory and try installing a package:

When you first run the pipenv install command, you will notice it creates a virtualenv, Pipfile and Pipfile.lock for you. Feel free to go ahead inspect their contents. If you’re using an IDE like PyCharm and want to configure your project interpreter, it would be a good idea to note down the virtualenv path.

Since we have installed Flask, let’s try and running a sample app. Here’s my super simple REST API built with Flask:

Assuming that you have the FLASK_APP environment variable set to app.py (which contains the above code), we can just run the app like this:

Any executables in the current environment can be run using the pipenv run command. But I know what you might be thinking – we want to do just flask run, not use the entire, long command. That’s easy too. We just need to activate the virtualenv with this command:

Now you can just do flask run or in fact run any executables in the way we’re used to doing.

Handling Dependencies

We can install and uninstall packages using the install and uninstall commands. When we install a new package, it’s added to our Pipfile and the lock file is updated as well. When we uninstall a package, the Pipfile and the lock files are again updated to reflect the change. The update command uninstalls the packages and installs them again so we have the latest updates.

If you would like to check your dependency graph, just use the graph command which will print out the dependencies in a nice format, kind of like this:

Pipenv is Awesome!

Trust me, it is! It packs a lot of cool and useful features that can help gear up your Python development workflow. There are just too many to cover in a blog post. I would recommend checking out the Pipenv Docs to get familiar with it more.

Categories
Python

Deploying A Flask based REST API to AWS Lambda (Serverless) using Zappa

I have heard about AWS Lambda and all the cool things happening in the serverless world. I have also deployed Go functions using the Apex framework for serverless deployment. But recently I have started working on some Python projects again and decided to see how well the Python community is adapting to the serverless era. Not to my surprise, the Python community is doing great as usual. I quickly found an awesome framework named Zappa which makes deploying Python code to AWS Lambda very easy. Python is already natively supported on the AWS Lambda platform. But with the native support you need to configure the API Gateway, S3 bucket and other stuff on your own. Thanks to Zappa, these things are now automated to our convenience. We can easily deploy WSGI apps as well. That means, we can now take our Flask / Django / API Star apps and deploy them to AWS Lambda – with ease and simplicity. In this blog post, I will quickly walk through how to deploy a flask based rest api to the serverless cloud. If you want to learn more about API integration you can look for Jitterbit.

Setup Flask App

Before we can get started, we need to create a simple flask app. Here’s a quick rest api (that doesn’t do much):

Let’s save the above code in app.py. We can now install Flask using pip:

And then run the code:

This should run our app and we should be able to visit http://127.0.0.1:5000/ to see the output.

Setting Up AWS

Please make sure you have an account for AWS where you have added your credit card and completed the sign up process. AWS Lambda has 1 million free requests per month which is promised to be always free (not for the first 12 months or anything). When you add your card, you shall also be eligible for a free tier of S3 for 12 months. So you won’t be charged for trying out a sample app deployment. So don’t worry about adding a card. In fact, adding a card is a requirement for getting the free tier.

Once you have your AWS account setup, click on your name (top right) and click “My Security Credentials”. From there, choose the “Access Keys” section and generate a new pair of key and secret. Store them in your ~/.aws/credentials file. AWS Cli (and Zappa) will use these to connect to AWS services and perform required actions. The file should look like this:

I have created two profiles here. Named profiles are useful if you have more than one accounts/projects/environments to work with. After adding the credentials, add the region information in ~/.aws/config:

This will mostly help with choosing the default region for your app. Once you have these AWS settings configured, you can get started with Zappa.

Install and Configure Zappa

First install Zappa:

Now cd into the project directory (where our flask app is). Then run:

Zappa should guide you through the settings it needs. It should also detect the Flask app and auto complete the app (app.app ) for you. Once the wizard finishes, you’re ready to deploy your API.

This should now deploy the app to the dev stage. You can configure different stages for your app in Zappa settings. Once you make some code changes, you can update the app:

Both of these commands should print out the url for the app. In my case, the url is: https://1gc1f80kb5.execute-api.us-east-2.amazonaws.com/dev 🙂

What’s Next?

Congratulations, you just deployed a Flask rest api to AWS Lambda using Zappa. You can make the url shorter by pointing a domain to it from your AWS console. To know more about Zappa and all the great things it can do, please check out Zappa on Github.

Categories
Golang

Golang: Interface

In Go or Golang, declaring an interface is pretty simple and easy.

We just defined an interface named Printer that required an implementer to have a method named Print which takes a string parameter and returns nothing. Interfaces are implemented implicitly in Go. Any type that has the Print(string) method implements the interface. There is no need to use any implements keyword or anything of that sort.

In the above example, the Terminal type implements the Printer interface because it implements the methods required by the interface. Here’s a runnable, full code example:

We declared our printer variable to be of type Printer which is the interface. Since the Terminal type implements the Printer interface, we can pass Terminal{} to the printer variable and later call the Print method on it.

Interface and the Method sets

As you can understand, a method set is a set of methods on a type. The method set of an interface type (for example Printer here) is it’s interface, that is the Print method in this example. The method set of a type T (for example Terminal) contains the methods which can take a T type receiver. In our above code, the Print method takes the type Terminal so it’s included in Terminal‘s method set. The corresponding pointer type, *T has a method set that includes all methods with a receiver type of *T as well as the methods defined on the receiver type T. So *Terminal type contains any method that either takes Terminal or Terminal as a receiver type. So the Print method is also in the method set for *Terminal .

Method Set of T includes all methods receiving just T.
Method Set of *T includes all methods receiving either T or *T.

So the method set of *T includes the method set of T anyway. But by now, you might be wondering why this is so important. It is very important to understand the method set of a type because whether it implements an interface or not depends on the method set. To understand things further, let’s take a quick look at the following example:

If you try to run this code on the go playground or try to run/compile it on your machine, you shall get an error message like this:

Can you guess what’s happening? Well, our Print method has a receiver type of *Terminal however we are trying to assign the type Terminal to printer. The Print method falls in the method set of *Terminal and not Terminal. So in this particular example, *Terminal type actually implements the interface, not the base Terminal type. We can just assign &Terminal to printer and it will work fine. Try the codes here – https://play.golang.org/p/MvyD0Ls8xb 🙂

Another interesting thing, since *Terminal also includes the method set defined on Terminal, this could would be valid just fine – https://play.golang.org/p/xDmNGBcwsM. This is why understanding the method set of a type is important to understand which interfaces it implements.

The Curious Case of Method Calls

We have seen how the method set of *T includes methods receiving both T and *T but the method set of T is confined to methods that only take T and not *T. Now you might be thinking – I have seen codes like the following snippet:

Here, the Print method receives a *Terminal type but how are we calling it on Terminal type? From what we have seen before, Terminal should not have the method set defined to take a *Terminal receiver, how is this call being made?

Well, the code x.m() works fine if the m method takes the x type as receiver. That is fine with us. But if the method m is to take the type *x and we try to call x.m() – that shouldn’t work, right? The proper call should be (&x).m() – no? Yes, correct. But Go provides us a shortcut here. If the method m is defined to take a *x type as receiver and base type x is addressable, x.m() works as a shortcut for (&x).m(). Go provides us with that shortcut to keep things simpler. So whether you have a pointer or a value, it doesn’t matter, as long as the type is addressable, you can call the method set of *x on x using the very same syntax. However, please remember that this shortcut is not available while working with interfaces.

The Empty Interface

The type interface{} has zero methods defined on it. And every type in Go implements zero or more methods. So their method set actually satisfies the emtpy interface aka interface{}. So if a variable is of type interface{}, we can pass any type to it.

We want to store different types in the same slice? Map values can be of different types? Just use interface{}.

So, when we’re not sure of a type, or we need the type to flexible / dynamic, we can use interface{} to store them.

Type Assertion

While we can store any type in a interface{} type, not all types are the same. For example, you can not use the string functions on an integer type. Go would not accept if you blindly want to pass interface{} in an operation where a very specific type is expected. Take a look:

Even though we have a string value stored against the name key, Go actually stores it as a type interface{} and thus it won’t allow us to use it like a string. Luckily, interface values do store the underlying value and type. So we can use type assertion to assert that the underlying value can behave like a certain type.

This works:

The unKnownMap["name"].(string) part – we’re doing the type assertion here. If the type assertion succeeds, we can use the value as a string. If it does not succeed, we will get a panic.

Getting Type of an interface{}

If you have an interface{} and want to know what it holds underneath, you can use the %T format in Printf family of calls.

Type Switch

You can also use a switch statement with an interface{} to deal with different possible types.

The i.(type) gets you the type of the variable. Please remember it only works with a switch statement.