I can't figure out how to call cloud.WithContext
and google.DefaultClient
if I have appengine.Context
and not context.Context
.
There are (old) "appengine" and (new) "google.golang.org/appengine" packages. The first one brings custom appengine.Context
when second one comes with context.Context
from "golang.org/x/net/context"
The whole google.golang.org/cloud
expects context.Context
only.
I would be happy to move to using new "google.golang.org/appengine"
, but I've stuck with runtime.RunInBackground
that have not been ported yet. From https://github.com/golang/appengine:
appengine/aetest
,appengine/cloudsql
andappengine/runtime
have not been ported yet.
What I could write if appengine/runtime
have been ported already:
import (
"golang.org/x/net/context"
"google.golang.org/appengine"
"google.golang.org/appengine/runtime"
"google.golang.org/cloud"
"google.golang.org/cloud/storage"
)
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
runtime.RunInBackground(c, func(ctx context.Context) {
hc, _ := google.DefaultClient(ctx, storage.ScopeFullControl)
cc := cloud.WithContext(ctx, appengine.AppID(ctx), hc)
…
})
}
but there is no "google.golang.org/appengine/runtime"
yet. So I have
runtime.RunInBackground(c, func(ctx appengine.Context) {
Google App Engine (GAE) is a platform-as-a-service product that provides web app developers and enterprises with access to Google's scalable hosting and tier 1 internet service. GAE requires that applications be written in Java or Python, store data in Google Bigtable and use the Google query language.
The App Engine standard environment is based on container instances running on Google's infrastructure. Containers are preconfigured with one of several available runtimes. The standard environment makes it easy to build and deploy an application that runs reliably even under heavy load and with large amounts of data.
Google App Engine is a service and a platform where you can develop and host web applications. You can learn more about Google App Engine at the official Google App Engine site. With App Engine integration, you can run and debug Google App Engine applications. A new project already includes app.
At the moment there is no way to get cloud context.Context
from (old) appengine.Context
.
Solution for Managed VM
A month ago BackgroundContext()
method was added to google.golang.org/appengine
(available for Managed VM only). This allows start goroutine and get cloud context.Context
without passing it into.
Solution for classic Appengine
There is no solution at the moment.
Do this:
func getCloudContext(appengineContext context.Context) context.Context {
hc := &http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(appengineContext, storage.ScopeFullControl),
Base: &urlfetch.Transport{Context: appengineContext},
},
}
return cloud.NewContext(appengine.AppID(appengineContext), hc)
}
Or if passing the credentials through the dev server isn't working, you can also use explicit credentials:
func getCloudContext(aeCtx context.Context) (context.Context, error) {
data, err := ioutil.ReadFile("/path/to/credentials.json")
if err != nil {
return nil, err
}
conf, err := google.JWTConfigFromJSON(
data,
storage.ScopeFullControl,
)
if err != nil {
return nil, err
}
tokenSource := conf.TokenSource(aeCtx)
hc := &http.Client{
Transport: &oauth2.Transport{
Source: tokenSource,
Base: &urlfetch.Transport{Context: aeCtx},
},
}
return cloud.NewContext(appengine.AppID(aeCtx), hc), nil
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With