Im trying to use the Go sdk for aws to download a file from s3 doing something similar to what has been done in the examples provided by aws: https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/davidbyttow/govips/v2/vips"
)
func handler(ctx context.Context, s3Event events.S3Event) {
for _, record := range s3Event.Records {
s3 := record.S3
sess, err := session.NewSession(&aws.Config{
Region: aws.String("<REGION>"),
})
if err != nil {
exitErrorf("cannot create s3 session, %v", err)
}
downloader := s3manager.NewDownloader(sess)
file, err := os.Create(filepath.Base(s3.Object.Key))
if err != nil {
exitErrorf("DownloadFile:::Unable to open file, %v", err)
}
defer file.Close()
numBytes, err := downloader.Download(file,
&s3.GetObjectInput{
Bucket: aws.String("<BUCKET>"),
Key: aws.String(s3.Object.Key),
})
if err != nil {
exitErrorf("Unable to download item %q, %v", s3.Object.Key, err)
}
fmt.Println("Downloaded", file.Name(), numBytes, "bytes")
}
When I try to build the project I get the errors:
"github.com/aws/aws-sdk-go/service/s3" imported and not used
and
s3.GetObjectInput is not a type
I have ran go get on the packages used and go mod tidy to sort out my go.mod file. It seems perfectly happy with the s3manager lines and the other aws packages and it is just complaining about the s3 references.
Is there something simple I am missing?
The package name of the imported package github.com/aws/aws-sdk-go/service/s3
is s3
, which is hidden by s3 := record.S3
. That's why you see the error.
The recommended solution is to modify s3 := record.S3
to choose another identity. For example, s3Entity := record.S3
. Don't forget to replace s3.Object.Key
with s3Entity.Object.Key
in the source code.
Another option is to give another name to the imported package. For example:
import awss3 "github.com/aws/aws-sdk-go/service/s3"
Reference from the "Declarations and scope" section of the spec:
A declaration binds a non-blank identifier to a constant, type, type parameter, variable, function, label, or package. ...
Go is lexically scoped using blocks:
- The scope of a predeclared identifier is the universe block.
- The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.
- The scope of the package name of an imported package is the file block of the file containing the import declaration.
- The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
- The scope of an identifier denoting a type parameter of a function or declared by a method receiver begins after the name of the function and ends at the end of the function body.
- The scope of an identifier denoting a type parameter of a type begins after the name of the type and ends at the end of the TypeSpec.
- The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
- The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.
An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration.
See also Import declarations.