diff --git a/appengine/bigquery/README.md b/appengine/bigquery/README.md new file mode 100644 index 0000000000..9df5d10368 --- /dev/null +++ b/appengine/bigquery/README.md @@ -0,0 +1,17 @@ +# Accessing BigQuery from App Engine + +This code has been written to support this [blog post][1]. + +You can run this application locally or deploy it to App Engine app servers. +To do so you will need the `goapp` tool included in the [Go App Engine SDK][2]. + +- get all the dependencies for this code snippet + + goapp get . + +- deploy to App Engine servers + + goapp deploy --application=[your-application-id] . + +[1]: https://medium.com/@francesc/accessing-bigquery-from-app-engine-d01823de81ee +[2]: https://cloud.google.com/appengine/downloads?hl=en diff --git a/appengine/bigquery/app.go b/appengine/bigquery/app.go new file mode 100644 index 0000000000..385678a2eb --- /dev/null +++ b/appengine/bigquery/app.go @@ -0,0 +1,81 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +// This App Engine application uses its default service account to list all +// the BigQuery datasets accessible via the BigQuery REST API. +package sample + +import ( + "fmt" + "net/http" + "strings" + + "golang.org/x/net/context" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/api/bigquery/v2" + "google.golang.org/appengine" + "google.golang.org/appengine/urlfetch" +) + +func init() { + http.HandleFunc("/", handle) +} + +func handle(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + + // create a new App Engine context from the request. + ctx := appengine.NewContext(r) + + // obtain the list of dataset names. + names, err := datasets(ctx) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text") + + if len(names) == 0 { + fmt.Fprintf(w, "no datasets visible") + } else { + fmt.Fprintf(w, "datasets:\n\t"+strings.Join(names, "\n\t")) + } +} + +// datasets returns a list with the ids of all the Big Query datasets visible +// with the given context. +func datasets(ctx context.Context) ([]string, error) { + // create a new authenticated HTTP client over urlfetch. + client := &http.Client{ + Transport: &oauth2.Transport{ + Source: google.AppEngineTokenSource(ctx, bigquery.BigqueryScope), + Base: &urlfetch.Transport{Context: ctx}, + }, + } + + // create the BigQuery service. + bq, err := bigquery.New(client) + if err != nil { + return nil, fmt.Errorf("could not create service: %v", err) + } + + // obtain the current application id, the BigQuery id is the same. + appID := appengine.AppID(ctx) + + // prepare the list of ids. + var ids []string + datasets, err := bq.Datasets.List(appID).Do() + if err != nil { + return nil, fmt.Errorf("could not list datasets for %q: %v", appID, err) + } + for _, d := range datasets.Datasets { + ids = append(ids, d.Id) + } + return ids, nil +} diff --git a/appengine/bigquery/app.yaml b/appengine/bigquery/app.yaml new file mode 100644 index 0000000000..8c32a94ff0 --- /dev/null +++ b/appengine/bigquery/app.yaml @@ -0,0 +1,7 @@ +version: 1 +runtime: go +api_version: go1 + +handlers: +- url: /.* + script: _go_app