Callum Slater

Callum Slater


Getting Started with AWS Lambda and Go

Originally published by Ran Ribenzaft at

Go is undoubtedly one of the fastest-growing languages today. Since its 1.0 release in March 2012, it has seen adopted in a vast number of industries, but particularly in the cloud computing space. From microservices to the tools and components that power some of the largest cloud infrastructures, it’s hard to ignore Go’s contribution.

Projects such as Docker and Kubernetes have helped shape the way we run code at scale today, while others like Terraform leverage infrastructure as code in the current multi-cloud and multi-provider world.

With such a track record, it’s no wonder that in a recent study published by HackerRank of over 70 thousand developers, 37.2% indicated that Go is a language they wish to learn in 2019. No other language scored as high, making Go, per this particular study, the language most developers want to learn in 2019.

Given this popularity, it’s also no surprise that AWS – a pioneer and de facto leader in serverless computing – had already added Go as a supported runtime to AWS Lambda back at the beginning of 2018.

Advantages of Go for AWS Lambda

While all Lambda runtimes offer the same advantages in terms of scalability and share many concepts, there are some notable advantages when you use Go: Runtime versioning scheme, cold start performance, and pricing.

Runtime Versioning

The Go runtime for AWS Lambda has a very significant difference from every other runtime available today. While other runtimes support only specific versions of a language (for example, Python 2.7, 3.6, and 3.7 are three separate runtimes), the Go runtime supports any 1.x release, which already spans over seven years of releases.

Whenever a new version of Go is released, it’s possible to use it from day one, without having to wait for AWS to release a newly updated runtime. Such a feature would not be possible were Go not a statically compiled language with its Go 1 compatibility guarantee.

Cold Starts

When a Lambda function hasn’t had an invocation for a while, or when a spike in traffic requires additional functions to spawn, there’s a small penalty associated with it – the often dreaded cold start. Fortunately, Go has one of the fastest cold start times. You can read more on how to minimize AWS Lambda cold starts here.


The pricing model of AWS Lambda is per invocation, plus the duration of the invocation rounded up to the nearest 100ms. The price per each 100ms also depends on the amount of memory allocated to the function.

While Go isn’t necessarily as memory-hungry as some dynamic languages, there is a small catch: a direct correlation between the CPU performance and allocated memory. While Go might also squeeze more performance out of a throttled CPU than some other languages, this remains an important point to consider. If you wish to learn more about this particular topic, be sure to read How to Make Lambda Faster: Memory Performance Benchmark.

With all this in mind, you can rest assured that Go is an excellent choice for AWS Lambda: A performant, cost-efficient language with the bonus of being able to run the latest (or even prerelease) version of the Go language without waiting for AWS to update their runtimes.

Getting Started

So, let’s get some coding done. You are going to create an HTTP triggered AWS Lambda function that responds with JSON. We’ll start by returning a response that contains the current time in UTC and then improve it to detect the requester’s timezone using a free third-party API, enabling us to also include the local time in the response.

Before we can start, however, there are a few prerequisites we must fulfill.


You’ll need an AWS account for this. If you don’t yet have one, sign up for a free account here. The AWS free tier includes one million invocations every month and enough credit to run a single 128MB function continuously, all at no charge.

For building and deploying your functions, you’ll be using the Serverless Framework, which is the most widely used tool for the job. Assuming you have a recent version of Node.js installed, you can install the Serverless CLI with the following npm command:

$ npm install -g serverless

Once you have the Serverless CLI installed, you must configure it to use the AWS access keys of your account:

$ serverless config credentials --provider aws --key <access key ID> --secret <secret access key>

If you don’t have Go installed yet, you can either download an installer from the official website or use your favorite package manager to install it.

The Lambda-Time Function

Now that you have everything you need, let’s create a new project using Go modules for your function. Let’s name the module lambda-time. In a new, empty directory, initialize the Go module, and install the AWS Lambda for Go library:

$ go mod init lambda-time
$ go get

After this, you can proceed to create a main.go file that implements your handler function and starts the process:

package main
import (
type response struct {
    UTC time.Time `json:"utc"`
func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    now := time.Now()
    resp := &response{
        UTC: now.UTC(),
    body, err := json.Marshal(resp)
    if err != nil {
        return events.APIGatewayProxyResponse{}, err
    return events.APIGatewayProxyResponse{Body: string(body), StatusCode: 200}, nil
func main() {

This previous code can be broken into a few simple steps:

  • Define a response struct that supports JSON serialization and defines the HTTP response body of a successful invocation of your AWS Lambda function.
  • Create a request handler function, which creates a response struct containing the current time in UTC and then proceeds to serialize it as JSON. In case the serialization fails, you return the error; if everything goes well, you respond with your serialized JSON as the response body and a status code of 200.
  • Register your handler function in the main function using the AWS Lambda for Go library.

The Handler Function

It’s worth taking some time to understand how the handler function works. While there are multiple valid handler signatures, the one you used is the complete one. The context argument provides information on the invoked function, its environment, and also the deadline of the invocation. Returning an error value from the handler function signals that the invocation failed and automatically logs the value of the error.

That leaves the request and response structs in your handler function signature. Lambda functions are invoked either by AWS services or by using an AWS SDK (e.g., from another Lambda function). Data passed in and out of a Lambda function is in JSON format. In your case, the AWS Lambda for Go library automatically handles the serialization and deserialization between JSON and Go values.

When calling Lambda functions using the AWS SDK, the structure of the input and output JSON data is up to the developer. For AWS Lambda functions invoked by AWS services, the data structure depends on the invoking service. Amazon API Gateway is the service that triggers Lambda functions in response to HTTP calls. For API Gateway, this means the request is always of type events.APIGatewayProxyRequest and the response will always be of type events.APIGatewayProxyResponse.

The AWS Lambda for Go library contains the data definitions for each AWS service that can invoke Lambda functions.


Your function is now ready and you can proceed by deploying it with the Serverless Framework. For that, we must first create a serverless.yml file that defines what we are deploying:

service: lambda-time
  name: aws
  runtime: go1.x
   - ./**
   - ./bin/**
    handler: bin/lambda-time
      - http:
          path: /
          method: get

Here you name both your service and function lambda-time, but a service could instead contain multiple functions with different names. You also need to configure your API Gateway by specifying that the function responds to HTTP events of a particular HTTP method and at a given request path.

Next up, build the code as an x86-64 Linux executable, and deploy it:

$ GOOS=linux GOARCH=amd64 go build -o bin/lambda-time .
$ serverless deploy

Once finished, the command prints the URL for the endpoint. Open it, and make sure it responds with the current time.

Improving Your Service

Now that you have a working service, you can improve it by also returning the time in the local timezone of the requester (based on IP address). To do so, add an HTTP client to your Lambda function along with a function that returns the timezone for a given IP address:

var httpClient = &http.Client{}
func timezone(ip string) *time.Location {
        resp, err := httpClient.Get("" + ip + "/timezone/")
        if err != nil {
                return nil
        defer resp.Body.Close()
        tz, err := ioutil.ReadAll(resp.Body)
        if err != nil {
                return nil
        loc, err := time.LoadLocation(string(tz))
        if err != nil {
                return nil
        return loc

By rebuilding and redeploying the Lambda function, you can now see the local timezone (assuming it is possible to determine based on IP):

$ GOOS=linux GOARCH=amd64 go build -o bin/lambda-time .
$ serverless deploy

You have now built a Lambda function that, while simple, demonstrates how to build an actual service. However, to make a production service, you’re still missing some crucial elements–monitoring, instrumentation, and tracing. Don’t wait for your first outage before considering implementing these.

Monitoring, Instrumentation, and Tracing

Epsagon has designed and built an extremely easy-to-use Go library for this purpose. If you haven’t signed up yet for a free trial, go ahead and get started!

Once you have your Epsagon API token, add it as an environment variable to the provider section of the serverless.yml so that it applies to all of your functions:

  name: aws
  runtime: go1.x
    EPSAGON_TOKEN: "<Epsagon API token>"

When done, install the library:

$ go get

By making only two minimal changes to your service, you will be able to add tracing and instrumentation:

import (
var httpClient = epsagonhttp.Wrap(http.Client{})
func main() {
                &epsagon.Config{ApplicationName: "lambda-time"},

All you had to do was wrap both your Lambda function handler and your HTTP client. The Epsagon library handles the rest. Now you can get full tracing and instrumentation, not only to your service but to outbound calls as well:

Epsagon Architecture View

You also get monitoring for all of your Lambda invocations and much more.


In this post, we’ve looked at some of the advantages of using Go for writing AWS Lambda functions. We saw what it takes to set up an environment to develop, build, and deploy functions with the Serverless Framework. We then proceeded to create and deploy a Lambda function behind an API Gateway that showcased a real-world usage scenario of calling third-party APIs. Finally, we added monitoring, instrumentation, and tracing by using the Epsagon for Go library.

Equipped with this knowledge, you can now start developing microservices in Go and deploying them in a serverless fashion using AWS Lambda. Remember – Serverless platforms can take care of running and scaling your code, but being able to troubleshoot and fix production issues quickly is vital to running a successful business. For this latter part, you can count on Epsagon to help you effectively monitor and troubleshoot your applications for optimal results.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Further reading

Learn How To Code: Google’s Go (golang) Programming Language

Go: The Complete Developer’s Guide (Golang)

Build Realtime Apps | React Js, Golang & RethinkDB

Go Programming Language Tutorial | Golang Tutorial For Beginners | Go / Golang Crash Course

Google’s Go Essentials For Node.js / JavaScript Developers

Moving from NodeJS to Go

Learn Go Programming - Golang Tutorial for Beginners

A guide to Golang e-commerce

AWS Certified Solution Architect Associate

AWS Lambda vs. Azure Functions vs. Google Functions

Running TensorFlow on AWS Lambda using Serverless

Deploy Docker Containers With AWS CodePipeline

A Complete Guide on Deploying a Node app to AWS with Docker

Create and Deploy AWS and AWS Lambda using Serverless Framework

Introduction To AWS Lambda

#go #aws #web-service #microservices #serverless

What is GEEK

Buddha Community

Getting Started with AWS Lambda and Go
Shubham Ankit

Shubham Ankit


How to Automate Excel with Python | Python Excel Tutorial (OpenPyXL)

How to Automate Excel with Python

In this article, We will show how we can use python to automate Excel . A useful Python library is Openpyxl which we will learn to do Excel Automation


Openpyxl is a Python library that is used to read from an Excel file or write to an Excel file. Data scientists use Openpyxl for data analysis, data copying, data mining, drawing charts, styling sheets, adding formulas, and more.

Workbook: A spreadsheet is represented as a workbook in openpyxl. A workbook consists of one or more sheets.

Sheet: A sheet is a single page composed of cells for organizing data.

Cell: The intersection of a row and a column is called a cell. Usually represented by A1, B5, etc.

Row: A row is a horizontal line represented by a number (1,2, etc.).

Column: A column is a vertical line represented by a capital letter (A, B, etc.).

Openpyxl can be installed using the pip command and it is recommended to install it in a virtual environment.

pip install openpyxl


We start by creating a new spreadsheet, which is called a workbook in Openpyxl. We import the workbook module from Openpyxl and use the function Workbook() which creates a new workbook.

from openpyxl
import Workbook
#creates a new workbook
wb = Workbook()
#Gets the first active worksheet
ws =
#creating new worksheets by using the create_sheet method

ws1 = wb.create_sheet("sheet1", 0) #inserts at first position
ws2 = wb.create_sheet("sheet2") #inserts at last position
ws3 = wb.create_sheet("sheet3", -1) #inserts at penultimate position

#Renaming the sheet
ws.title = "Example"

#save the workbook = "example.xlsx")


We load the file using the function load_Workbook() which takes the filename as an argument. The file must be saved in the same working directory.

#loading a workbook
wb = openpyxl.load_workbook("example.xlsx")




#getting sheet names
result = ['sheet1', 'Sheet', 'sheet3', 'sheet2']

#getting a particular sheet
sheet1 = wb["sheet2"]

#getting sheet title
result = 'sheet2'

#Getting the active sheet
sheetactive =
result = 'sheet1'




#get a cell from the sheet
sheet1["A1"] <
  Cell 'Sheet1'.A1 >

  #get the cell value
ws["A1"].value 'Segment'

#accessing cell using row and column and assigning a value
d = ws.cell(row = 4, column = 2, value = 10)




#looping through each row and column
for x in range(1, 5):
  for y in range(1, 5):
  print(x, y, ws.cell(row = x, column = y)

#getting the highest row number

#getting the highest column number

There are two functions for iterating through rows and columns.

Iter_rows() => returns the rows
Iter_cols() => returns the columns {
  min_row = 4, max_row = 5, min_col = 2, max_col = 5
} => This can be used to set the boundaries
for any iteration.


#iterating rows
for row in ws.iter_rows(min_row = 2, max_col = 3, max_row = 3):
  for cell in row:
  print(cell) <
  Cell 'Sheet1'.A2 >
  Cell 'Sheet1'.B2 >
  Cell 'Sheet1'.C2 >
  Cell 'Sheet1'.A3 >
  Cell 'Sheet1'.B3 >
  Cell 'Sheet1'.C3 >

  #iterating columns
for col in ws.iter_cols(min_row = 2, max_col = 3, max_row = 3):
  for cell in col:
  print(cell) <
  Cell 'Sheet1'.A2 >
  Cell 'Sheet1'.A3 >
  Cell 'Sheet1'.B2 >
  Cell 'Sheet1'.B3 >
  Cell 'Sheet1'.C2 >
  Cell 'Sheet1'.C3 >

To get all the rows of the worksheet we use the method worksheet.rows and to get all the columns of the worksheet we use the method worksheet.columns. Similarly, to iterate only through the values we use the method worksheet.values.


for row in ws.values:
  for value in row:



Writing to a workbook can be done in many ways such as adding a formula, adding charts, images, updating cell values, inserting rows and columns, etc… We will discuss each of these with an example.




#creates a new workbook
wb = openpyxl.Workbook()

#saving the workbook"new.xlsx")




#creating a new sheet
ws1 = wb.create_sheet(title = "sheet 2")

#creating a new sheet at index 0
ws2 = wb.create_sheet(index = 0, title = "sheet 0")

#checking the sheet names
wb.sheetnames['sheet 0', 'Sheet', 'sheet 2']

#deleting a sheet
del wb['sheet 0']

#checking sheetnames
wb.sheetnames['Sheet', 'sheet 2']




#checking the sheet value

#adding value to cell
ws['B2'] = 367

#checking value




We often require formulas to be included in our Excel datasheet. We can easily add formulas using the Openpyxl module just like you add values to a cell.

For example:

import openpyxl
from openpyxl
import Workbook

wb = openpyxl.load_workbook("new1.xlsx")
ws = wb['Sheet']

ws['A9'] = '=SUM(A2:A8)'"new2.xlsx")

The above program will add the formula (=SUM(A2:A8)) in cell A9. The result will be as below.




Two or more cells can be merged to a rectangular area using the method merge_cells(), and similarly, they can be unmerged using the method unmerge_cells().

For example:
Merge cells

#merge cells B2 to C9
ws['B2'] = "Merged cells"

Adding the above code to the previous example will merge cells as below.




#unmerge cells B2 to C9

The above code will unmerge cells from B2 to C9.


To insert an image we import the image function from the module openpyxl.drawing.image. We then load our image and add it to the cell as shown in the below example.


import openpyxl
from openpyxl
import Workbook
from openpyxl.drawing.image
import Image

wb = openpyxl.load_workbook("new1.xlsx")
ws = wb['Sheet']
#loading the image(should be in same folder)
img = Image('logo.png')
ws['A1'] = "Adding image"
#adjusting size
img.height = 130
img.width = 200
#adding img to cell A3

ws.add_image(img, 'A3')"new2.xlsx")




Charts are essential to show a visualization of data. We can create charts from Excel data using the Openpyxl module chart. Different forms of charts such as line charts, bar charts, 3D line charts, etc., can be created. We need to create a reference that contains the data to be used for the chart, which is nothing but a selection of cells (rows and columns). I am using sample data to create a 3D bar chart in the below example:


import openpyxl
from openpyxl
import Workbook
from openpyxl.chart
import BarChart3D, Reference, series

wb = openpyxl.load_workbook("example.xlsx")
ws =

values = Reference(ws, min_col = 3, min_row = 2, max_col = 3, max_row = 40)
chart = BarChart3D()
ws.add_chart(chart, "E3")"MyChart.xlsx")


How to Automate Excel with Python with Video Tutorial

Welcome to another video! In this video, We will cover how we can use python to automate Excel. I'll be going over everything from creating workbooks to accessing individual cells and stylizing cells. There is a ton of things that you can do with Excel but I'll just be covering the core/base things in OpenPyXl.

⭐️ Timestamps ⭐️
00:00 | Introduction
02:14 | Installing openpyxl
03:19 | Testing Installation
04:25 | Loading an Existing Workbook
06:46 | Accessing Worksheets
07:37 | Accessing Cell Values
08:58 | Saving Workbooks
09:52 | Creating, Listing and Changing Sheets
11:50 | Creating a New Workbook
12:39 | Adding/Appending Rows
14:26 | Accessing Multiple Cells
20:46 | Merging Cells
22:27 | Inserting and Deleting Rows
23:35 | Inserting and Deleting Columns
24:48 | Copying and Moving Cells
26:06 | Practical Example, Formulas & Cell Styling

📄 Resources 📄
OpenPyXL Docs: 
Code Written in This Tutorial: 


Cross-account access to invoke AWS lambda using AWS CDK

If you are here, you may have a pretty good knowledge of how to use AWS CDK for defining cloud infrastructure in code and provisioning it through AWS. So let’s get started on how to grant permission to your lambda function to access the resources in another AWS account.

Let’s say you have two accounts called Account A and Account B, and you need to give permission to lambda function in Account A (ex: 11111111)to access the resources in Account B(22222222). You can easily do this by assuming an IAM Role in Account B and then uses the returned credentials to invoke AWS resources in Account B.

#acces #account #aws #lambda #aws lambda #aws cdk

Monty  Boehm

Monty Boehm


Twitter.jl: Julia Package to Access Twitter API


A Julia package for interacting with the Twitter API.

Twitter.jl is a Julia package to work with the Twitter API v1.1. Currently, only the REST API methods are supported; streaming API endpoints aren't implemented at this time.

All functions have required arguments for those parameters required by Twitter and an options keyword argument to provide a Dict{String, String} of optional parameters Twitter API documentation. Most function calls will return either a Dict or an Array <: TwitterType. Bad requests will return the response code from the API (403, 404, etc).

DataFrame methods are defined for functions returning composite types: Tweets, Places, Lists, and Users.


Before one can make use of this package, you must create an application on the Twitter's Developer Platform.

Once your application is approved, you can access your dashboard/portal to grab your authentication credentials from the "Details" tab of the application.

Note that you will also want to ensure that your App has Read / Write OAuth access in order to post tweets. You can find out more about this on Stack Overflow.


To install this package, enter ] on the REPL to bring up Julia's package manager. Then add the package:

julia> ]
(v1.7) pkg> add Twitter

Tip: Press Ctrl+C to return to the julia> prompt.


To run Twitter.jl, enter the following command in your Julia REPL

julia> using Twitter

Then the a global variable has to be declared with the twitterauth function. This function holds the consumer_key(API Key), consumer_secret(API Key Secret), oauth_token(Access Token), and oauth_secret(Access Token Secret) respectively.

twitterauth("6nOtpXmf...", # API Key
            "sES5Zlj096S...", # API Key Secret
            "98689850-Hj...", # Access Token
            "UroqCVpWKIt...") # Access Token Secret
  • Ensure you put your credentials in an env file to avoid pushing your secrets to the public 🙀.

Note: This package does not currently support OAuth authentication.

Code examples

See runtests.jl for example function calls.

using Twitter, Test
using JSON, OAuth

# set debugging


mentions_timeline_default = get_mentions_timeline()
tw = mentions_timeline_default[1]
tw_df = DataFrame(mentions_timeline_default)
@test 0 <= length(mentions_timeline_default) <= 20
@test typeof(mentions_timeline_default) == Vector{Tweets}
@test typeof(tw) == Tweets
@test size(tw_df)[2] == 30

user_timeline_default = get_user_timeline(screen_name = "randyzwitch")
@test typeof(user_timeline_default) == Vector{Tweets}

home_timeline_default = get_home_timeline()
@test typeof(home_timeline_default) == Vector{Tweets}

get_tweet_by_id = get_single_tweet_id(id = "434685122671939584")
@test typeof(get_tweet_by_id) == Tweets

duke_tweets = get_search_tweets(q = "#Duke", count = 200)
@test typeof(duke_tweets) <: Dict

#test sending/deleting direct messages
#commenting out because Twitter API changed. Come back to fix
# send_dm = post_direct_messages_send(text = "Testing from Julia, this might disappear later $(time())", screen_name = "randyzwitch")
# get_single_dm = get_direct_messages_show(id =
# destroy = post_direct_messages_destroy(id =
# @test typeof(send_dm) == Tweets
# @test typeof(get_single_dm) == Tweets
# @test typeof(destroy) == Tweets

#creating/destroying friendships
add_friend = post_friendships_create(screen_name = "kyrieirving")

unfollow = post_friendships_destroy(screen_name = "kyrieirving")
unfollow_df = DataFrame(unfollow)
@test typeof(add_friend) == Users
@test typeof(unfollow) == Users
@test size(unfollow_df)[2] == 40

# create a cursor for follower ids
follow_cursor_test = get_followers_ids(screen_name = "twitter", count = 10_000)
@test length(follow_cursor_test["ids"]) == 10_000

# create a cursor for friend ids - use barackobama because he follows a lot of accounts!
friend_cursor_test = get_friends_ids(screen_name = "BarackObama", count = 10_000)
@test length(friend_cursor_test["ids"]) == 10_000

# create a test for home timelines
home_t = get_home_timeline(count = 2)
@test length(home_t) > 1

# TEST of cursoring functionality on user timelines
user_t = get_user_timeline(screen_name = "stefanjwojcik", count = 400)
@test length(user_t) == 400
# get the minimum ID of the tweets returned (the earliest)
minid = minimum( for x in user_t);

# now iterate until you hit that tweet: should return 399
# WARNING: current versions of julia cannot use keywords in macros? read here:
# eventually replace since_id = minid
tweets_since = get_user_timeline(screen_name = "stefanjwojcik", count = 400, since_id = 1001808621053898752, include_rts=1)

@test length(tweets_since)>=399

# testing get_mentions_timeline
mentions = get_mentions_timeline(screen_name = "stefanjwojcik", count = 300) 
@test length(mentions) >= 50 #sometimes API doesn't return number requested (twitter API specifies count is the max returned, may be much lower)
@test Tweets<:typeof(mentions[1])

# testing retweets_of_me
my_rts = get_retweets_of_me(count = 300)
@test Tweets<:typeof(my_rts[1])

Want to contribute?

Contributions are welcome! Kindly refer to the contribution guidelines.

Linux: Build Status 

CodeCov: codecov

Author: Randyzwitch
Source Code: 
License: View license

#julia #api #twitter 

Cache secrets using AWS Lambda extensions

What is the AWS Lambda extension?

A month back AWS announced a preview of Lambda Extensions, a new way to easily integrate Lambda with your favorite monitoring, observability, security, and governance tools. Extensions can be published as Lambda layers, there are two types are extension:

  • Internal extensions → Run as part of the runtime process, in-process with your code. Internal extensions enable use cases such as automatically instrumenting code.
  • External extensions → Allow you to run separate processes from the runtime but still within the same execution environment as the Lambda function. External extensions can start before the runtime process and can continue after the runtime shuts down. These extensions run as companion processes to Lambda functions.

#aws #aws-secrets-manager #lambda #aws lambda

Fannie  Zemlak

Fannie Zemlak


What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features