GithubHelp home page GithubHelp logo

lifadev / archive_aws-lambda-go-shim Goto Github PK

View Code? Open in Web Editor NEW
791.0 31.0 66.0 604 KB

Author your AWS Lambda functions in Go, effectively.

Home Page: https://github.com/eawsy/aws-lambda-go-shim

License: Apache License 2.0

Makefile 18.57% C 4.54% Go 31.04% Python 31.21% C# 2.13% Java 2.03% JavaScript 1.97% Shell 8.50%
aws aws-lambda lambda golang go serverless

archive_aws-lambda-go-shim's Introduction

THIS PROJECT IS DEPRECATED IN FAVOR OF ITS SUCCESSOR
aws/aws-lambda-go



Powered by Amazon Web Services Created by eawsy

eawsy/aws-lambda-go-shim

Author your AWS Lambda functions in Go, effectively.

Status License Help Social

AWS Lambda lets you run code without thinking about servers. For now, you can author your AWS Lambda functions, natively, in C#, Java, Node.js and Python. This project provides a native and full-featured shim for authoring your AWS Lambda functions in Go.

Table of Contents

      generated with DocToc

Preview

package main

import "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"

func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
	return "Hello, World!", nil
}
wget -qO- https://github.com/eawsy/aws-lambda-go-shim/raw/master/src/preview.bash | bash
# "Hello, World!" executed in 0.45 ms

🐣 If you like the experience, please spread the word!

Features

Serialization Context Logging Exceptions Environment Events API Gateway
OK OK OK OK OK OK OK

Performance

DISCLAIMER: We do not intend to compare Go with other languages but to appreciate the overhead of our shim compared to officially supported AWS Lambda languages.

😎 It is the 2nd fastest way to run an AWS Lambda function and makes the Node.js spawn process technique obsolete.

Benchmark

How It Works

Quick Hands-On

  1. Requirements

    docker pull eawsy/aws-lambda-go-shim:latest
    go get -u -d github.com/eawsy/aws-lambda-go-core/...
    wget -O Makefile https://git.io/vytH8
  2. Code

    package main
    
    import (
      "encoding/json"
    
      "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
    )
    
    func Handle(evt json.RawMessage, ctx *runtime.Context) (interface{}, error) {
      // ...
    }
  3. Build

    make
  4. Deploy

    You can use your preferred deployment method by providing it the following configuration:

    • Runtime: python2.7
    • Handler: handler.Handle

    For example, if you deploy your function through the AWS Lambda Management Console, you will have to fill a bunch of parameters like:

Under the Hood

Considering for example the above preview section, we have the following structure:

.
└── preview
    ├── handler.go
    └── Makefile

The handler.go file is where resides the main entrypoint of your AWS Lambda function. There is no restriction on how many files and dependencies you can have, nor on how you must name your files and functions. Nevertheless however we advocate to retain the handler name and to use Handle as the name of your entrypoint.

Let's review the content of handler.go:

1 package main
2 
3 import "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
4 
5 func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
6 	return "Hello, World!", nil
7 }

Main Package

For a seamless experience we leverage Go 1.8 plugins to separate the shim from your code. At run time, AWS Lambda loads our pre-compiled shim which in turn loads your code (your plugin). A plugin is a Go main package and that is why your entrypoint must be in the main package, as seen at line 1. Notice that this restriction only applies to your entrypoint and you are free to organize the rest of your code in different packages.

Runtime Context

While your function is executing, it can interact with AWS Lambda to get useful runtime information such as, how much time is remaining before AWS Lambda terminates your function, the AWS request id, etc. This information is passed as the second parameter to your function via the runtime.Context object, as seen at line 5.
With eawsy/aws-lambda-go-core we empower you with a full-featured context object to access any available information in the exact same way that official AWS Lambda runtimes do. This is the only dependency you ever need, as seen in line 3.

Get Dependencies

eawsy/aws-lambda-go-core dependency can be retrieved using the well known go get command:

go get -u -d github.com/eawsy/aws-lambda-go-core/...

Go vendoring is also supported out of the box and behaves the same way expected when building usual go projects:

  • If the preview folder is inside GOPATH, then vendor folder prevails over GOPATH dependencies.
  • If the preview folder is outside GOPATH, then vendor folder is ignored in favor of GOPATH dependencies.

Handler Signature

5 func Handle(evt interface{}, ctx *runtime.Context) (string, error) {
6 	return "Hello, World!", nil
7 }

For AWS Lambda being able to call your handler, you have to make it visible outside your plugin, as seen at line 5. There is no other naming restriction but keep in mind that if you change the name of your function, you must also update it in the AWS Lambda configuration.

Tip: Use a variable to expose a handler from the inside of a package:

var Handle = mypackage.MyHandle

For the rest, the handler follows the AWS Lambda programming model by:

  • Taking 2 parameters:

  • Returning 2 values:

    • Result – The first return value is automatically json marshalled and forwarded back to the client.
      You are free to use the well known interface{} type, any other valid Go type or even your own custom type to leverage fine grained json marshalling.
    • Error – The second return value notifies AWS Lambda an error occurred during execution. As expected it prevails over the first return value. You are free to return native Go errors or custom ones:
      type CustomError struct {
          s string
      }
      
      func (e *CustomError) Error() string {
          return e.s
      }
      
      func Handle(evt interface{}, ctx *runtime.Context) (interface{}, error) {
        return nil, &CustomError{"somthing bad happened"}
      }

Logging

In line with the AWS Lambda programming model, one should be able to output logs using standard abilities of the language. Your function can contain logging statements using the official Go log package and AWS Lambda writes theses logs to AWS CloudWatch Logs asynchronously. There is no restriction on how to configure or use the Go log package.

package main

import (
	"log"

	"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
)

func Handle(evt interface{}, ctx *runtime.Context) (interface{}, error) {
	log.Println("Hello, World!")
	return nil, nil
}

Exceptions

In the course of a normal and controlled execution flow, you can notify AWS Lambda an error occurred by returning an error as explained above.
In case of unexpected situations when the ordinary flow of control stops and begins panicking and if you have not any recover mechanism in place, then the stack trace is logged in AWS CloudWatch Logs and AWS Lambda is notified an error occurred.

Building

We provide a Docker image based on Amazon Linux container image to build your binary in the exact same environment than AWS Lambda. This image embeds our pre-compiled shim along with helper scripts to package your function. You can use it as such or build your own custom image from it:

docker pull eawsy/aws-lambda-go-shim:latest

Although not strictly required, we also provide an example Makefile to streamline common use cases. You are free to customize, modify and adapt it to your needs. Let's review its content briefly:

HANDLER ?= handler
PACKAGE ?= $(HANDLER)

docker:
  @docker run ...

build:
  @go build ...

pack:
  @pack ...
  • Customize – The first two environment variables allow you to customize the name of your handler and the generated package:

    make
    .
    └── preview
        ├── handler.go
        ├── handler.so
        ├── handler.zip
        └── Makefile
    HANDLER=myhandler PACKAGE=mypackage make
    .
    └── preview
        ├── handler.go
        ├── Makefile
        ├── myhandler.so
        └── mypackage.zip
  • Dockerize – The docker target runs our Docker image and executes the rest of the build process inside it.

  • Build – The build target builds your code with the plugin build mode. Feel free to customize build flags.

  • Package – The pack target is by far the most important one. It packages your previously built plugin and inject our pre-compiled shim, with the correct name, into the package.
    Be careful if you customize the example Makefile or if you build your own custom image, the way the shim is injected into the package ensures its correct functioning.

Deployment

The only intent of this project is to provide the most seamless and effective way to run Go on AWS Lambda. We do not provide any sugar and you are free to use your tools of predilection for deployment with the following settings in AWS Lambda:

  • Runtime: python2.7
  • Handler: handler.Handle (unless customized as explained above)

Known Limitations

  • The behavior of the Go fmt package is non-deterministic in AWS CloudWatch Logs. Please use Go log package instead.

Edge Behaviors

Even if some of these behaviors can be overcome, we mimic the official AWS Lambda runtimes.

  • Log statements are not visible during initialization. If you log anything in the init function, it won't be written in AWS CloudWatch Logs.

About

eawsy

This project is maintained and funded by Alsanium, SAS.

We ❤️ AWS and open source software. See our other projects, or hire us to help you build modern applications on AWS.

Contact

We want to make it easy for you, users and contributers, to talk with us and connect with each others, to share ideas, solve problems and make help this project awesome. Here are the main channels we're running currently and we'd love to hear from you on them.

Twitter

eawsyhq

Follow and chat with us on Twitter.

Share stories!

Gitter

eawsy/bavardage

This is for all of you. Users, developers and curious. You can find help, links, questions and answers from all the community including the core team.

Ask questions!

GitHub

pull requests & issues

You are invited to contribute new features, fixes, or updates, large or small; we are always thrilled to receive pull requests, and do our best to process them as fast as we can.

Before you start to code, we recommend discussing your plans through the eawsy/bavardage channel, especially for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give you feedback on your design, and help you find out if someone else is working on the same thing.

Write code!

License

This product is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this product except in compliance with the License. See LICENSE and NOTICE for more information.

Trademark

Alsanium, eawsy, the "Created by eawsy" logo, and the "eawsy" logo are trademarks of Alsanium, SAS. or its affiliates in France and/or other countries.

Amazon Web Services, the "Powered by Amazon Web Services" logo, and AWS Lambda are trademarks of Amazon.com, Inc. or its affiliates in the United States and/or other countries.

archive_aws-lambda-go-shim's People

Contributors

cristim avatar dragonfax avatar fsenart avatar lion3ls avatar masneyb avatar michael-k avatar temoto avatar tleyden avatar tobowers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

archive_aws-lambda-go-shim's Issues

First invocation sometimes crashes in handle()

About 20% of first time invocations of my lambda handler crash before my code is called. This happens somewhere in handle(). I don't see this exception when everything is running normally. It only appears to happen for the first call right after I upload a new version of my lambda handler. Any ideas?

unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x7fd476570ec8]

goroutine 17 [running, locked to thread]:
	runtime.throw(0x7fd4765f3250, 0x5)
	/usr/local/go/src/runtime/panic.go:596 +0x97 fp=0xc4202878f0 sp=0xc4202878d0
	runtime.sigpanic()
	/usr/local/go/src/runtime/signal_unix.go:297 +0x290 fp=0xc420287940 sp=0xc4202878f0
	runtime.call64(0xc4202477a0, 0x7fd46f727cd0, 0xc420247800, 0x1000000030)
	/usr/local/go/src/runtime/asm_amd64.s:515 +0x48 fp=0xc420287990 sp=0xc420287940
	reflect.Value.call(0x7fd46fb61f40, 0x7fd46f727cd0, 0x13, 0x7fd4765f2ff8, 0x4, 0xc420287e10, 0x2, 0x2, 0x7fd4768259c0, 0x7fd47684d368, ...)
	/usr/local/go/src/reflect/value.go:434 +0x921 fp=0xc420287cd8 sp=0xc420287990
	reflect.Value.Call(0x7fd46fb61f40, 0x7fd46f727cd0, 0x13, 0xc420287e10, 0x2, 0x2, 0xc4202f68f8, 0x193, 0x7fd476549aa8)
	/usr/local/go/src/reflect/value.go:302 +0xa6 fp=0xc420287d40 sp=0xc420287cd8
	main.handle(0x14e2614, 0x13f9324, 0x14b60e4, 0xc420287eb0, 0xc420287eb8, 0x0)
	/build/src/runtime.go:140 +0x4e1 fp=0xc420287e50 sp=0xc420287d40
	main._cgoexpwrap_dd780bcacc70_handle(0x14e2614, 0x13f9324, 0x14b60e4, 0x0, 0x0, 0x0)
	_/build/src/_obj/_cgo_gotypes.go:127 +0x9a fp=0xc420287e90 sp=0xc420287e50
	runtime.call64(0x0, 0x7ffc5d059ee8, 0x7ffc5d059f80, 0x30)
	/usr/local/go/src/runtime/asm_amd64.s:515 +0x4a fp=0xc420287ee0 sp=0xc420287e90
	runtime.cgocallbackg1(0x0)
	/usr/local/go/src/runtime/cgocall.go:301 +0x1a1 fp=0xc420287f58 sp=0xc420287ee0
	runtime.cgocallbackg(0x0)
	/usr/local/go/src/runtime/cgocall.go:184 +0x86 fp=0xc420287fc0 sp=0xc420287f58
	runtime.cgocallback_gofunc(0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/asm_amd64.s:767 +0x71 fp=0xc420287fe0 sp=0xc420287fc0
	runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc420287fe8 sp=0xc420287fe0

goroutine 18 [syscall, locked to thread]:
	runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1

goroutine 19 [syscall]:
	os/signal.signal_recv(0x0)
	/usr/local/go/src/runtime/sigqueue.go:116 +0x118
	os/signal.loop()
	/usr/local/go/src/os/signal/signal_unix.go:22 +0x24
	created by os/signal.init.1
	/usr/local/go/src/os/signal/signal_unix.go:28 +0x43

error when building

Hi, I'm getting the next output when trying to build.

pkg-config --cflags python2
Package python2 was not found in the pkg-config search path.
Perhaps you should add the directory containing `python2.pc'
to the PKG_CONFIG_PATH environment variable
No package 'python2' found
pkg-config: exit status 1
make: *** [build] Error 2
Makefile:44: recipe for target 'docker' failed
make: *** [docker] Error 2

tests:

➜  ~ docker run -it eawsy/aws-lambda-go-shim:latest pkg-config --cflags python2
Package python2 was not found in the pkg-config search path.
Perhaps you should add the directory containing `python2.pc'
to the PKG_CONFIG_PATH environment variable
No package 'python2' found
➜  ~ docker run -it eawsy/aws-lambda-go-shim:latest pkg-config --list-all  
shared-mime-info shared-mime-info - Freedesktop common MIME database

details:

OS: Linux Mint 18.2 Sonya
GO: version go1.9.2 linux/amd64
➜  ~ docker image inspect eawsy/aws-lambda-go-shim:latest
[
    {
        "Id": "sha256:463bc78cf42899598c499dd10d6a608a285ba8c79439a8b1de6fad8822ae53a2",
        "RepoTags": [
            "eawsy/aws-lambda-go-shim:latest"
        ],
        "RepoDigests": [
            "eawsy/aws-lambda-go-shim@sha256:92f3aa256e4744f841d2b789717ebe45076248ac6cb4df3857fb2d303b6498db"
        ],

➜ ~ docker version

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:24:23 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:00 2017
 OS/Arch:      linux/amd64
 Experimental: false



README Step 3 Deploy is confusing

It says:

3 - Deploy
Runtime: python2.7
Handler: handler.Handle

what does this mean?

I'm looking at my previous commits to see how I got aws-lambda-go-shim working in the past .. and I see that I added a .yaml file, but I don't even see any .yaml files mentioned in the aws-lambda-go-shim README. Have things changed and .yaml files are no longer needed?

Makefile doesn't work with Windows

I suppose you're not surprised, but even if one has GNU make for Windows installed, the Makefile still doesn't work on windows because 1) it assumes the path on the dev machine will be a valid path inside the container, and 2) it uses shell tricks that don't directly work on Windows.

To work around that, I created a powershell script that will do the "docker" step of the build. I am sharing it here and giving permission to edit or incorporate it at will, in the hopes that this will help other people. The functionality should be identical to the Makefile, except that it doesn't support multiple GOPATHs.

build.ps1

$path=$MyInvocation.MyCommand.Path
$parts=$path.Split("\")
$project=$parts[$parts.Length-2]
$team=$parts[$parts.Length-3]
$cloud=$parts[$parts.Length-4]

$handler=if ($env:HANDLER) { $env:HANDLER } else { "handler" }
$package=if ($env:PACKAGE) { $env:PACKAGE } else { $handler }

docker run --rm -e HANDLER=$handler -e PACKAGE=$package -v $env:GOPATH\:/go/ `
    -w /go/src/$cloud/$team/$project `
    eawsy/aws-lambda-go-shim:latest make all

Use vendored dependencies

Hi,

I've modified your example Makefile slightly (to use govendor) and it generates a zip file which I deploy to Lambda:

index.go:

package main

import "C"

import (
	"fmt"
	"github.com/eawsy/aws-lambda-go-core/service/lambda/runtime"
	"github.com/eawsy/aws-lambda-go-event/service/lambda/runtime/event/apigatewayproxyevt"
)

func Handle(evt apigatewayproxyevt.Event, ctx *runtime.Context) (interface{}, error) {
	fmt.Println(evt)
	return "testing...", nil
}

I deploy with config:

  • Runtime: Python 2.7
  • Handler: index.Handle

When I test the function in the Lambda web console it responds:

{
  "errorMessage": "Unable to import module 'index'"
}

and the logs say:

Unable to import module 'index': dynamic module does not define init function (initindex)

My Makefile contains:

PACKAGE ?= index
HANDLER ?= index

lambda/$(PACKAGE).zip: clean
	@echo -ne "build..."\\r
	@govendor build -buildmode=plugin -ldflags='-w -s' -o lambda/$(HANDLER).so ./lambda
	@chown $(shell stat -c '%u:%g' .) lambda/$(HANDLER).so
	@echo -ne "build, pack"\\r
	@cd lambda; zip -q $(PACKAGE).zip $(HANDLER).so
	@echo -ne "build, pack, inject"\\r
	@cd lambda; zip -q -r -j $(PACKAGE).zip /shim
	@chown $(shell stat -c '%u:%g' .) lambda/$(PACKAGE).zip
	@echo -ne "DONE!"\\n

Builds failing since the last image push

I'm getting Unable to find image 'eawsy/aws-lambda-go-shim:latest' locally latest: Pulling from eawsy/aws-lambda-go-shim Status: Downloaded newer image for eawsy/aws-lambda-go-shim:latest lambda.go:17:2: cannot find package "github.com/eawsy/aws-lambda-go-core/service/lambda/runtime" in any of: /usr/local/go/src/github.com/eawsy/aws-lambda-go-core/service/lambda/runtime (from $GOROOT) /root/go/src/github.com/eawsy/aws-lambda-go-core/service/lambda/runtime (from $GOPATH)
using the latest image. No problems before that.

Image with alpine linux

I tried to build an image from alpine linux with this Dockerfile.base

FROM golang:alpine

ENV PKG_CONFIG_PATH /usr/lib/pkgconfig

ENV PACKAGES="\
 bash \
 git \
 findutils \
 build-base \
 ca-certificates \
 python2 \
 python2-dev \
 zip \
 pkgconf \
"

RUN apk update \
&& apk upgrade \
&& apk add --no-cache $PACKAGES \
&& ln -s $PKG_CONFIG_PATH/python-2.7.pc $PKG_CONFIG_PATH/python2.7.pc \

It can build code successfully in local env but when I upload .zip file to aws lambda, it had an error when executing function:

START RequestId: 36ac546c-3390-11e7-ab02-71150c75a5ff Version: $LATEST
Unable to import module 'handler': libc.musl-x86_64.so.1: cannot open shared object file: No such file or directory

It seem like there 's a problem with musl package so I 've installed musl but it not fixed.

Can you create an alpine image instead of Amazon linux, I think it will be much smaller in size.

Error traces don't show github.com/pkg/errors fill stack trace

I use the github.com/pkg/errors package for the reasons Dave Cheney outlined here.

However the shim isn't showing the full stack trace. In the logs from sam local start-api I see:

InvalidClientTokenId: The security token included in the request is invalid.
	status code: 403, request id: fe72a854-d6d3-11e7-b66d-05886b9fd61d: withStack
Traceback (most recent call last):
  File "runtime/proxy.py", line 45, in _handle
withStack: InvalidClientTokenId: The security token included in the request is invalid.
	status code: 403, request id: fe72a854-d6d3-11e7-b66d-05886b9fd61d

Ideally this would be a log with the full stack trace that the errors package helps build up.

not enough arguments, expected at least 3, got 0
main.parseArgs
        /home/dfc/src/github.com/pkg/errors/_examples/wrap/main.go:12
main.main
        /home/dfc/src/github.com/pkg/errors/_examples/wrap/main.go:18
runtime.main
        /home/dfc/go/src/runtime/proc.go:183
runtime.goexit
        /home/dfc/go/src/runtime/asm_amd64.s:2059

That stack trace is only visible in golang with fmt.Printf("%v\n", err), so it's understandable the shim isn't calling into it.

I don't get the inner workings of the shim yet so I'm not sure if this would be an easy fix or not. Guidance is appreciated.

Handler return values

I don't know if this is my personal mistake or something in the source code. I followed the example here: https://github.com/eawsy/aws-lambda-go-shim, trying to return custom error when something goes wrong. However, in CloudWatch logs I always see errors returned, even after I removed all my business logic in the handler.

func Handle(event json.RawMessage, ctx *runtime.Context) (interface{}, error) {
    return nil, &CustomError{"failure"}
}

I mean even the code above will return error in CloudWatch log:

failure: CustomError
Traceback (most recent call last):
File "runtime/proxy.py", line 44, in _handle
CustomError: failure

Did I do sth wrong?

Go path must be relative?

Hey folks, getting back into development today and I ran into the following issue. Thoughts?

Step to reproduce:

  1. Update makefile to latest (see below for makefile)
  2. Execute make build in project directory

Expected Result:

  1. .zip file created as expected

Actual Result:

  1. I get the following error:
go build -buildmode=plugin -ldflags='-w -s ' -o handler.so
go: GOPATH entry is relative; must be absolute path: "C/Users/hhjones/go".
For more details see: 'go help gopath'
make: *** [build] Error 2

Makefile:

#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
#

HANDLER ?= handler
PACKAGE ?= $(HANDLER)

ifeq ($(OS),Windows_NT)
	GOPATH ?= $(USERPROFILE)/go
	GOPATH := $(subst ;,:/,$(subst \,/,$(subst :,,$(GOPATH))))
	CURDIR := /$(subst :,,$(CURDIR))
	RM := del /q
else
	GOPATH ?= $(HOME)/go
	RM := rm -f
endif

MAKEFILE = $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))

docker:
	docker run --rm\
		-e HANDLER=$(HANDLER)\
		-e PACKAGE=$(PACKAGE)\
		-e GOPATH=$(GOPATH)\
		-e LDFLAGS='$(LDFLAGS)'\
		-v $(CURDIR):$(CURDIR)\
		$(foreach GP,$(subst :, ,$(GOPATH)),-v $(GP):$(GP))\
		-w $(CURDIR)\
		eawsy/aws-lambda-go-shim:latest make -f $(MAKEFILE) all

.PHONY: docker

all: build pack perm

.PHONY: all

build:
	go build -buildmode=plugin -ldflags='-w -s $(LDFLAGS)' -o $(HANDLER).so

.PHONY: build

pack:
	pack $(HANDLER) $(HANDLER).so $(PACKAGE).zip

.PHONY: pack

perm:
	chown $(shell stat -c '%u:%g' .) $(HANDLER).so $(PACKAGE).zip

.PHONY: perm

clean:
	$(RM) $(HANDLER).so $(PACKAGE).zip

.PHONY: clean

preview.bash not working on osx

\e[32m> Invoke AWS Lambda function\e[0m
base64: invalid option -- d
Usage:	base64 [-hvD] [-b num] [-i in_file] [-o out_file]
  -h, --help     display this message
  -D, --decode   decodes input
  -b, --break    break encoded string into num character lines
  -i, --input    input file (default: "-" for stdin)
  -o, --output   output file (default: "-" for stdout)
17245-jstillwell:aws-go-test jstillwell$ aws --version
aws-cli/1.11.118 Python/2.7.13 Darwin/16.7.0 botocore/1.5.81

Installed via brew on macos 10.12

how to use environment variable

i want to use environment variable to post the message to slack.
so i add the environment variable like below in Makefile.

docker:
	docker run --rm\
		-e SlackUrl=$(SlackUrl)\
		-e HANDLER=$(HANDLER)\
		-e PACKAGE=$(PACKAGE)\
		-e GOPATH=$(GOPATH)\
		-e LDFLAGS='$(LDFLAGS)'\
		-v $(CURDIR):$(CURDIR):Z\
		$(foreach GP,$(subst :, ,$(GOPATH)),-v $(GP):$(GP)):Z\
		-w $(CURDIR)\
		eawsy/aws-lambda-go-shim:latest make -f $(MAKEFILE) all

and use like below. but get empty.

url := os.Getenv("SlackUrl")  // url is ""

how should i do?

Support for custom error types

This might be a long shot but on the 16th of march a feature was added to AWS Step Functions that allows you to drive state transitions based on specific errors from your Lambda functions; a feature I was waiting for. A NodeJS example of this can be found here: https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-handling-error-conditions.html and the announcement here https://aws.amazon.com/about-aws/whats-new/2017/03/aws-step-functions-adds-customized-error-handling-for-aws-lambda-functions/

They didn't add matching based on JSON fields or string matching and only check the error type as returned by the runtime. With the awesome wrapper Go you guys made it currently doesn't seem possible (https://github.com/eawsy/aws-lambda-go-shim/blob/81ecb522e11dbd6096b6219fa66d9992e3410b1f/src/proxy.py#L48) to use this feature, is this correct? Is there any way of adding this?

You guys rock! Cheers, Ad

Deployment size (shim)

Hi

Can we do anything about the deployment size, at least decrease it? It seems too weird for me to see 8MB of code for a single hello world lambda function.

Regards

Runtime panic

Hey,

I am going crazy trying to figure this panic out. It doesn't happen all the time but if I run a small test with 1000 requests per second against the lambda function at-least 100 fail with this result.

unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x7faf0b42df68]

goroutine 17 [running, locked to thread]:
runtime.throw(0x7faf0b4b02d0, 0x5)
/usr/local/go/src/runtime/panic.go:596 +0x97 fp=0xc4201a78f0 sp=0xc4201a78d0
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:297 +0x290 fp=0xc4201a7940 sp=0xc4201a78f0
runtime.call64(0xc4201dbf50, 0x7faf038aa9c0, 0xc4201dbfb0, 0x1000000030)
/usr/local/go/src/runtime/asm_amd64.s:515 +0x48 fp=0xc4201a7990 sp=0xc4201a7940
reflect.Value.call(0x7faf03c59d20, 0x7faf038aa9c0, 0x13, 0x7faf0b4b0078, 0x4, 0xc4201a7e10, 0x2, 0x2, 0x7faf0b6e29c0, 0x7faf0b70a368, ...)
/usr/local/go/src/reflect/value.go:434 +0x921 fp=0xc4201a7cd8 sp=0xc4201a7990
reflect.Value.Call(0x7faf03c59d20, 0x7faf038aa9c0, 0x13, 0xc4201a7e10, 0x2, 0x2, 0xc4200726f8, 0x193, 0x7faf0b406b48)
/usr/local/go/src/reflect/value.go:302 +0xa6 fp=0xc4201a7d40 sp=0xc4201a7cd8
main.handle(0x23e29f4, 0x2332eb4, 0x23e23a4, 0xc4201a7eb0, 0xc4201a7eb8, 0x0)
/build/src/runtime.go:140 +0x4e1 fp=0xc4201a7e50 sp=0xc4201a7d40
main._cgoexpwrap_dd780bcacc70_handle(0x23e29f4, 0x2332eb4, 0x23e23a4, 0x0, 0x0, 0x0)
_/build/src/_obj/_cgo_gotypes.go:127 +0x9a fp=0xc4201a7e90 sp=0xc4201a7e50
runtime.call64(0x0, 0x7ffc8d2d1728, 0x7ffc8d2d17c0, 0x30)
/usr/local/go/src/runtime/asm_amd64.s:515 +0x4a fp=0xc4201a7ee0 sp=0xc4201a7e90
runtime.cgocallbackg1(0x0)
/usr/local/go/src/runtime/cgocall.go:301 +0x1a1 fp=0xc4201a7f58 sp=0xc4201a7ee0
runtime.cgocallbackg(0x0)
/usr/local/go/src/runtime/cgocall.go:184 +0x86 fp=0xc4201a7fc0 sp=0xc4201a7f58
runtime.cgocallback_gofunc(0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/runtime/asm_amd64.s:767 +0x71 fp=0xc4201a7fe0 sp=0xc4201a7fc0
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc4201a7fe8 sp=0xc4201a7fe0

goroutine 18 [syscall, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1

This panic seems to be happening before executing any of my code. If anything I can trace it to the handle function inside the src/runtime.go

API Gateway integration - 5xx Error

I have managed to deploy the hello world example. However i would like to integrate the lambda with API Gateway. I have created my API gateway method and choose the golang lambda function but i get "message": "Internal server error" when i call the http endpoint from postman.

Problem with using context.log method

Like I described below there is issue with using context.log method:

serverless/serverless#4544

Which is resulting with problem on local invocation.
Situation is not clear with used method here:
https://github.com/eawsy/aws-lambda-go-shim/blob/a9e5c8b1c1f09a38d3706e552c87ad945299f1f4/src/proxy.py#L45

is not documented in official documentation:
http://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html#python-context-object-methods

hoverer exist on AWS stack:
https://gist.github.com/gene1wood/c0d37dfcb598fc133a8c

I see two options:

  • add it to fake context: serverless/serverless#4544 (however its not officially documented)
  • replace it in proxy, (with logger or other print method):
import json
import os
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

import runtime

def dump(obj):
    if hasattr(obj, '__slots__'):
        return {slot: getattr(obj, slot) for slot in obj.__slots__}
    return obj.__dict__

class Proxy(object):
    def __getattr__(self, name):
        if name == "init":
            return lambda: None
        runtime.lookup(name)
        return self._handle

    def _handle(self, evt, ctx):
        return json.loads(runtime.handle(
            json.dumps(evt),
            json.dumps(ctx, default=dump),
            json.dumps({k: v for k, v in ((k, os.getenv(k)) for k in (
                "AWS_ACCESS_KEY_ID",
                "AWS_SECRET_ACCESS_KEY",
                "AWS_SESSION_TOKEN",
                "AWS_SECURITY_TOKEN",
                "_X_AMZN_TRACE_ID",
            )) if v}),
            logger.info, ctx.get_remaining_time_in_millis))

I'm looking forward to discuss about it

Update Go to 1.9

It would be nice to update the shim to 1.9, hopefully it fixes some of the current limitations, such as the one about the number of exported symbols in the module, currently limited to 8.

"make" process never exits on macOS

I ran make but the process doesn't seem to ever stop (I let it run for about 15 minutes now), there seems to be a handler.zip and handler.so however. It just doesn't exit even though the build succeeded.

I'm using gnu make 4.2.1 and docker 17.06 with docker 1.8.3

Unable to import module 'lambda': plugin.Open: /var/task/lambda.so: invalid ELF header

Hello,

I've updated both go package and docker image.

Below the content of my zip file:
zipinfo -m lambda.zip
Archive: lambda.zip 2860048 bytes 5 files
-rw-r--r-- 2.0 unx 72464 b- 0% stor 9-Apr-17 17:09 lambda.so
-rw-r--r-- 2.0 unx 928 b- 0% stor 8-Apr-17 00:18 lambda/init.pyc
-rw-r--r-- 2.0 unx 1800 b- 0% stor 8-Apr-17 00:18 lambda/proxy.pyc
-rw-r--r-- 2.0 unx 2782688 b- 0% stor 8-Apr-17 00:18 lambda/runtime.so
-rw-r--r-- 3.0 unx 2126 tx 26% defN 6-Apr-17 16:30 config.json
5 files, 2860006 bytes uncompressed, 2859450 bytes compressed: 0.0%

My go file got a simple Handle method:
func Handle(evt *s3evt.Event, ctx *runtime.Context) (interface{}, error) {
...
}

But when I test my lambda, I got this error:
START RequestId: 6b614679-1d47-11e7-acac-6309a8d92cc6 Version: $LATEST
Unable to import module 'lambda': plugin.Open: /var/task/lambda.so: invalid ELF header

END RequestId: 6b614679-1d47-11e7-acac-6309a8d92cc6
REPORT RequestId: 6b614679-1d47-11e7-acac-6309a8d92cc6 Duration: 0.33 ms Billed Duration: 100 ms

Any idea ?

Thanks,

Ludovic

Handler parameter unmarshalling not working

Hi!

I was trying to use the automatic parameter unmarshalling, but it doesn't seem to work.

I'm using the eawsy/aws-lambda-go-event repo for the event objects. Consider the following handler:

func Handle(event *dynamodbstreamsevt.Event, ctx *runtime.Context) (interface{}, error) {
    fmt.Print(event)
    return nil, nil
}

When I deploy and run this lambda function, a few weird symptoms:

  • no CloudWatch Log Group is ever created for the function
  • Lambda times out the execution after 5 min (that's the timeout I configured for the function)

If I simply change event *dynamodbstreamsevt.Event to event json.RawMessage (and, naturally, remove the import of dynamodbstreamsevt), the code runs successfully and prints the byte array.

The event I'm sending through the Lambda dashboard to test the function is a sample DynamoDB Update event.

Any ideas?

Thanks!
Bruno

Windows 7 MakeFile issue

The make fails with below command. I am using cygwin64 for make. Am I missing something here ?

C:\docker>make
docker run --rm
-e HANDLER=handler
-e PACKAGE=handler
-e GOPATH=/C/Users/user/go
-e LDFLAGS=''
-v /C/docker:/C/docker
-v /C/Users/user/go:/C/Users/user/go
-w /C/docker
eawsy/aws-lambda-go-shim:latest make -f makefile all
make: makefile: No such file or directory
make: *** No rule to make target `makefile'. Stop.
make: *** [docker] Error 2

dir command:

Directory of C:\docker

10/23/2017 12:16 PM

.
10/23/2017 12:16 PM ..
10/23/2017 12:11 PM main
10/25/2017 01:34 PM 2,213 Makefile
10/23/2017 12:16 PM preview

Building in Fedora 26 fails.

Hello again,

I'm trying this project in a Fedora distro however when invoking make it fails on me, I'm trying to debug but I'm not sure whats going on, creating this issue here if anyone run into this too.

To reproduce, you just need to follow the tutorial: https://github.com/eawsy/aws-lambda-go-shim#quick-hands-on
Here's the log:

$ make
make: stat: Makefile: Permission denied
make: *** No rule to make target `all'.  Stop.
make: *** [Makefile:11: docker] Error 2

I already tried to change the permission of Makefile to 777 but still doesn't work.

simple app failing with 'dynamic module does not define init function'

https://github.com/QuorumControl/failingapp

START RequestId: 58debea0-1ec6-11e7-887b-b5fd3e416142 Version: $LATEST
Unable to import module 'handler': dynamic module does not define init function (inithandler)

I'm pretty confused as to what's happening. I've been using your excellent software and I can still deploy one of my apps successfully, but not the one I'm working on and not the extremely simple app linked above.

If you are to run ./deploy.sh in there, you'll need to change the s3 bucket.

Make file errors

The instructions do not work

docker: Error response from daemon: invalid volume spec ":/tmp": invalid volume specification: ':/tmp'.
See 'docker run --help'.
Makefile:33: recipe for target 'all' failed
make: *** [all] Error 125

I chaged the make file "$(PWD):/tmp" to "$PWD:/tmp" and then I get this error

make: *** No rule to make target `_all'. Stop.
Makefile:33: recipe for target 'all' failed
make: *** [all] Error 2

Cannot use handler with invalid signature

Hi eawsy team, first of all, great library and thanks for open sourcing this.

I was able to get aws-lambda-go library working with the serverless framework, code here https://github.com/yunspace/serverless-golang

However when I upgraded to aws-lambda-go-shim, code here: https://github.com/yunspace/serverless-golang/tree/aws-lambda-go-shim I kept getting the following error:

make sls-all
make sls-invoke
{
    "errorMessage": "Cannot use handler 'Handle' with invalid signature"
}

I tried renamed the handler to foo.Bar on purpose to avoid clashing with python handler.Handler. but that didn't help.

The function itself is actually quite simple: https://github.com/yunspace/serverless-golang/blob/aws-lambda-go-shim/handler.go#L10

I then skipped serverless and tried to deploy using AWS commandline directly:

make aws-all
make aws-invoke
{
    "StatusCode": 200
}

plus I get a out file with the same error message. I looked in Cloudtrail and couldn't find anything meaningful either. Is there anything obvious I'm missing? Please help! I trust that the code base and the Makefiles should make reproducing this quite easy.

How to access req/resp?

In the event I'd like to return something sensible instead of JSON. Like an HTML/UI, or a fast marshal/unmarshal format such as PROTOBUF.

SSL certificates cannot be loaded

Hi!

For some reason, when using this new version my code fails to make any HTTPS connections. I investigated and noticed that x509.SystemCertPool() returns a pool with no certificates. I checked that the CA certificate files are indeed there in the Lambda environment, but it fails. I then tried to copy-and-paste the x509/example_test.go test functions, specifically ExampleCertificate_Verify() and ExampleParsePKIXPublicKey() https://golang.org/src/crypto/x509/example_test.go?m=text and it fails when parsing the certificate files.

I also tried to go-bindata a PEM file with certificates that I can for sure parse on my local machine and then try to have x509.SystemCertPool() add that, but I get the same certificate parsing issue.

It's very strange: parsing certificates fail in the Lambda environment, but it works on my machine.

With the previous version (ie, eawsy/aws-lambda-go), it works fine! The exact same code, with the exact same certificate data and tests, works fine on that previous version.

Have you seen this? Any ideas what could be causing it?

Thanks!
Bruno

Issue with "error" values

Hi!

I've identified an issue with "error" return values. If my Golang handler returns an error, the Lambda function invocation still completes successfully. That is, the Python shim isn't reporting an error to the Lambda runtime - instead, it is ending successfully, returning an object like {"errorMessage": "whatever"}.

It seems like the Lambda dashboard does indeed renders this as an error, however the execution is still reported to have been completed successfully.

I noticed this when I first tried to integrate a Golang Lambda function with the recently released AWS Step Functions service. Step Functions error detection mechanism for Task states running a Lambda function depend on the Lambda function correctly reporting error conditions. I wrote a very simple Golang Lambda handler function that would simply return nil, errors.New("blah"), and I noticed that a State Machine invoking that task would complete successfully, with the successful output being reported as {"errorMessage": ...}. The expected result would be for the State Machine execution to fail. I then wrote a trivial pure Python handler that would simply throw an error, and the State Machine did identify the error.

It seems like something that's not easy to fix... but I could be wrong.

Any ideas?

Cheers!

example doesn't work

Thank you for this very promising approach to run go on lambda!

When I try to submit a lambda function as described in the example I get the following error:

START RequestId: 517245b7-e880-11e6-9666-116d097ce2b1 Version: $LATEST
Unable to import module 'handler': plugin.Open: plugin was built with a different version of package github.com/eawsy/aws-lambda-go-core/service/lambda/runtime

END RequestId: 517245b7-e880-11e6-9666-116d097ce2b1
REPORT RequestId: 517245b7-e880-11e6-9666-116d097ce2b1	Duration: 0.24 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 18 MB	

I'm using the docker image eawsy/aws-lambda-go-shim:latest - I've tried the two different versions of github.com/eawsy/aws-lambda-go-core available, aa9f99 and 2d5865, but both produce the same error.

I've rebuild the docker containers locally to ensure that along the way it's the same version of the plugin which is being used, but the error persists.

Q: how to get a working setup?

Docker Build AWS Lambda function error

I am encountering below error on CentOS 7.

docker: Error response from daemon: Failed to initialize logging driver: InvalidParameterException: 1 validation error detected: Value 'eawsy/aws-lambda-go-shim:latest/goofy_jang/86708dc91ade4f34f6a378059f811b228879a35c5809e23cba84a1f72935bd14' at 'logStreamName' failed to satisfy constraint: Member must satisfy regular expression pattern: [^:*]*
	status code: 400, request id: f89491bd-41e2-11e7-a7a4-93e07a8be471.
make: *** [docker] Error 125

Here is the detailed log

# wget -qO- https://github.com/eawsy/aws-lambda-go-shim/raw/master/src/preview.bash | bash
> Pull AWS Lambda build environment from Docker Hub
latest: Pulling from eawsy/aws-lambda-go-shim
Digest: sha256:e7d0182f0703226449446dfbf726dbab4ad35e1960b9a0e1870d80edef34f7ca
Status: Image is up to date for eawsy/aws-lambda-go-shim:latest

> Download AWS Lambda Go dependencies from Github
github.com/eawsy/aws-lambda-go-core (download)

> Download handy Makefile from Github
--2017-05-26 17:14:30--  https://github.com/eawsy/aws-lambda-go-shim/raw/master/src/Makefile.example
Resolving github.com (github.com)... 192.30.255.113, 192.30.255.112
Connecting to github.com (github.com)|192.30.255.113|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://raw.githubusercontent.com/eawsy/aws-lambda-go-shim/master/src/Makefile.example [following]
--2017-05-26 17:14:31--  https://raw.githubusercontent.com/eawsy/aws-lambda-go-shim/master/src/Makefile.example
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.28.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.28.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2296 (2.2K) [text/plain]
Saving to: ‘Makefile’

100%[====================================================================================================================================================================================================>] 2,296       --.-K/s   in 0s

2017-05-26 17:14:31 (41.4 MB/s) - ‘Makefile’ saved [2296/2296]


> Check AWS Lambda basic execution role

An error occurred (NoSuchEntity) when calling the GetRole operation: Role not found for lambda_basic_execution

> Create AWS Lambda basic execution role
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "AROAITSGKDWXY7EHC6EFI",
        "CreateDate": "2017-05-26T07:14:31.707Z",
        "RoleName": "lambda_basic_execution",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXX:role/lambda_basic_execution"
    }
}

> Build AWS Lambda function
docker: Error response from daemon: Failed to initialize logging driver: InvalidParameterException: 1 validation error detected: Value 'eawsy/aws-lambda-go-shim:latest/goofy_jang/86708dc91ade4f34f6a378059f811b228879a35c5809e23cba84a1f72935bd14' at 'logStreamName' failed to satisfy constraint: Member must satisfy regular expression pattern: [^:*]*
	status code: 400, request id: f89491bd-41e2-11e7-a7a4-93e07a8be471.
make: *** [docker] Error 125

This is my go environment.

# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/root/golang"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build243335846=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

Running exec.Command within Lambda

Is it possible to package and run executables using this? I can't seem to get it to work. I have scenarios where I need to package and run an executable as part of a lambda call (git for instance) and I can't seem to get it to find my executable.

Problem with running code in lambda

On my local tests with amazon Linux container everything fine and runs and works. But when I deploy it to the lambda I got:

invalid character 'ó' looking for beginning of value: SyntaxError Traceback (most recent call last): File "runtime/proxy.py", line 44, in _handle SyntaxError: invalid character 'ó' looking for beginning of value

Incorrect make file path.

Was running into an issue where the Makefile would not successfully run make docker.

I think there is a path error with WORKDIR on line 32. There is a / missing at the end of the variable. It should be WORKDIR = $(CURDIR:$(GOPATH)%=/go/%) instead of WORKDIR = $(CURDIR:$(GOPATH)%=/go%).

Correct me I am wrong but don't think this is specific to my machine.

Use a custom Marshaler

I would like to be able to return protobuf marshaled as json back from the Handle function. I know that the current handler calls json.Marshal on the value returned from the lambda. Is there a way to easily override this behavior and use the json marshaler in protobufs instead?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.