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.

Categories
Golang

Golang: Making HTTP Requests

Go aka Golang is a very promising programming language with a lot of potential. It’s very performant, easy to grasp and maintain, productive and backed by Google. In our earlier posts, we have tried to provide guidelines to learn Go and later we saw how to work with JSON in Go. In this blog post, we’re going to see how we can make http requests using Go. We shall make use of the net/http package in Go which provides all the stuff we need to make http requests or create new http servers. That is, this package would help you do all things “http”. To check / verify that we made correct requests, we would be using httpbin which is a nice service to test our http client requests.

A Simple HTTP Request

Let’s make a very simple GET request and see how we can read the response. We would be sending a simple HTTP GET request to https://httpbin.org/get and read the response. For that we can just import the net/http package and use the http.Get function call. Let’s see an example:

We have created a separate MakeRequest function and called it from our main function. So going ahead, we will just see the changes inside this function and won’t need to think about the entire program. Inside this function, we have passed the url to http.Get and received two values – the response object and any errors that might have happened during the operation. We did a check to see if there were any errors. If there weren’t any errors, err would be nil. Please note that this err would be reported only if there was an issue connecting to the server and getting a response back. However, it would not be concerned about what http status code the server sent. For example, if the server sends a http 500 (which is internal server error), you will get that status code and error message on the resp object, not on err.

Next, we read the resp.Body which implements the io.ReadCloser interface and we can use ioutil.ReadAll to fully read the response. This function also returns two values – a byte slice ([]byte) and err. Again, we check for any potential errors in reading the response body. If there were no errors, we print out the body. Please note the string(body) part. Here, we’re converting the byte slice to a string. If we don’t do it, log.Println would print out representation of the byte slice, a list of all the bytes in that slice, individually. But we want a string representation. So we go ahead and make the conversion.

We would see the printed output is a JSON string. You will notice the httpbin service outputs JSON messages. So in the next example, we would see how we can send and read JSON messages.

JSON Requests and Responses

Now let’s send a JSON message. How do we do that? If you’re coming from Python / Node / Ruby, you might be used to passing a dictionary like structure to your favorite requests library and just mention it should be sent as JSON. Your library does the conversion for you and sends the request with required headers. In Go, however, things are more explicit, which is a good thing in fact. You will know what you’re doing, how you’re doing it. If the JSON related functionality is new to you, please do check our blog post – Golang: Working with JSON.

In Go, we would first convert our data structure to a byte slice containing the JSON representation of the data. Then we pass it to the request with the proper content type. Let’s see a code example:

We first created message which is a map containing a string value, an integer value and another embedded map. Then we json.Marshal it to get the []byte out of it. We also check for any errors that might happen during the marshalling. Next, we make a POST request using the http.Post function. We pass the url, our content type, which is JSON and then we create and pass a new bytes.Buffer object from the bytes representation. Why do we need to create a buffer here? The http.Post function expects an implementation of io.Reader – which is a brilliant design, anything that implements an io.Reader can be passed here. So we could even read this part from disk or network or any custom readers we want to implement. In our case, we can just create a bytes buffer which implements the io.Reader interface. We send the request and check for errors.

Next we declare another result variable (which is also a map type) to store the results returned from the request. We could read the full body first (like previous example) and then do json.Unmarshal on it. However, since the resp.Body is an io.Reader, we can just pass it to json.NewDecoder and then call Decode on it. Remember, we have to pass a pointer to our map, so we passed &result instead of just result.  The Decode function returns an error too. But we assumed it would not matter and didn’t check. But best practice would have been to handle it as well. We logged the result and result["data"]. The httpbin service sends different information about the request as the response. You can see those in the result map. If you want to see the data you sent, they will be in the data key of the result map.

Posting Form

In our last example, we have submitted JSON payload. What if we wanted to submit form values? We have the handy http.PostForm function for that. This function takes the url and url.Values from net/url package. The url.Values is a custom type which is actually map[string][]string internally. That is – it’s a map which contains string keys and against each key, there can be multiple string values ([]string). In a form request, you can actually submit multiple values against one field name. That’s the reason it’s a slice of string, instead of just a key to value mapping.

Here’s an example code snippet:

We would be reading the form key from the result map to retrieve our form values. We have seen how we can easily send form values using the net/http package. Next we would like to send a file along with typical form fields. For that we would also need to learn how to customize http requests on our own.

Custom Clients / Requests

The http.Get, http.Post or http.PostForm calls we have seen so far uses a default client already created for us. But now we are going to see how we can initialize our own Client instances and use them to make our own Requests. Let’s first see how we can create our own clients and requests to do the same requests we have made before. A quick example follows:

As you can see, we just take a new instance of http.Client and then create a new request by calling http.NewRequest function. It takes the http method, url and the request body. In our case, it’s a plain GET request, so we pass nil for the body. We then call the Do method on the client  and parse the response body. So that’s it – create a client, create a request and then let the client Do the request. Interestingly the client also has convenient methods like Get, Post, PostForm – so we can directly use them. That’s what http.Get, http.Post, http.PostForm and other root level functions actually do. They call these methods on the DefaultClient which is already created beforehand. In effect, we could just do:

And it would work similarly. Now you might be wondering – why not just use the DefaultClient, why create our own? What is the benefit?

Customizing the Client

If we look at the definition of the http.Client structure, it has these fields:

If we want, we can set our own transport implementation, we can control how the redirection is handled, pass a cookie jar to save cookies and pass them to the next request or simply set a timeout. The timeout part is often very significant in making http requests. The DefaultClient does not set a timeout by default. So if a malicious service wants, it can start blocking your requests (and your goroutines) indefinitely, causing havoc in your application. Customizing the client gives us more control over how the requests are sent.

File Upload

For uploading files while sending a http request, we need to use the mime/multipart package with the net/http package. We will first see the code example and then walk through it to understand what we’re doing. The code might seem a lot (it includes a lot of error handling) and complex. But please bear with me, once you go through the code and understand what’s happening, it will seem so simpler 🙂

So what are we doing here?

  • First we are opening the file we want to upload. In our case, I have created a file named “name.txt” that just contains my name.
  • We create a bytes.Buffer to hold the request body we will be passing with our http.Request later on.
  • We create a multipart.Writer object and pass a pointer to our bytes.Buffer object so the multipart writer can write necessary bytes to it.
  • The multipart writer has convenient methods to create a form file or a form field. It gives us back a writer to which we can write our file content or the field values. We create a file field and copy our file contents to it. Then we create a normal field and write “Value” to it.
  • Once we have written our file and normal form field, we call the Close method on the multipart writer object. Closing it writes the final, ending boundary to the underlying bytes.Buffer object we passed to it. This is necessary, otherwise the request body may remain incomplete.
  • We create a new post request like we saw before. We passed the bytes.Buffer we created as the request body. The body now contains the multi part form data written with the help of the mime/multipart package.
  • We send the request as before. But we set the content type by calling multiPartWriter.FormDataContentType() – which ensures the correct content type and boundary being set.
  • We decode the response from httpbin and check the output.

If everything goes well, we will see the form field and the file name in the response we received from httpbin. The concept here is simple. We are sending a http request with a custom body. We could construct the request body ourselves but we just took the help of the mime/multipart package to construct it in a relatively easier fashion.

Always Close The Response Body

Here’s a lesson I learned the hard way. When we make a http request, we get a response and an error back. We may feel lazy and decide not to check for errors or close the response body (just like in the examples above). And from the laziness comes disaster. If we do not close the response body, the connection may remain open and cause resource leak. But if the error is not nil that is in case of an error, the response can be nil. So we can’t just do a defer resp.Body.Close() in this case. We have to properly check error and then close the response body.

Always Use a Timeout

Try to use your own http client and set a timeout. Not setting a timeout can block the connection and the goroutine and thus cause havoc. So do something like this: