I am trying to use Google Translate API on Windows(my own computer). I have an issue with default credentials.
Error: **translate.NewClient: dialing: google: could not find default credentials.
I have enough balance in google cloud.
I started Translate API. (API Enabled)
I added $env:GOOGLE_APPLICATION_CREDENTIALS="KEY_PATH"
package main
import (
"context"
"fmt"
"log"
"cloud.google.com/go/storage"
"cloud.google.com/go/translate"
"golang.org/x/text/language"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
)
func translateTextWithModel(targetLanguage, text, model string) (string, error) {
// targetLanguage := "ja"
// text := "The Go Gopher is cute"
// model := "nmt"
ctx := context.Background()
lang, err := language.Parse(targetLanguage)
if err != nil {
return "", fmt.Errorf("language.Parse: %v", err)
}
client, err := translate.NewClient(ctx)
if err != nil {
return "", fmt.Errorf("translate.NewClient: %v", err)
}
defer client.Close()
resp, err := client.Translate(ctx, []string{text}, lang, &translate.Options{
Model: model, // Either "nmt" or "base".
})
if err != nil {
return "", fmt.Errorf("Translate: %v", err)
}
if len(resp) == 0 {
return "", nil
}
return resp[0].Text, nil
}
func main() {
Json_path := "C:/Users/Mels/Documents/GoogleTools/cred-9dfos6bb49f.json"
ProjectID := "cred"
fmt.Println("RUNNING...")
explicit(Json_path, ProjectID)
fmt.Println(translateTextWithModel("ja", "Hello World", "nmt"))
}
// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
ctx := context.Background()
client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
if err != nil {
log.Fatal(err)
}
defer client.Close()
fmt.Println("Buckets:")
it := client.Buckets(ctx, projectID)
for {
battrs, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(battrs.Name)
}
}
JSON File
{
"type": "service_account",
"project_id": "xxxxxxx",
"private_key_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----XXXXXXXX-----END PRIVATE KEY-----\n",
"client_email": "xxxxxx#xxxxxx.iam.gserviceaccount.com",
"client_id": "11111111111",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxx%xxxxxxx.iam.gserviceaccount.com"
}
If the library can't find the default credentials, then you can try to create a client with the credentials path.
Even if this might not be the best option for you (although I prefer it to the env variable), it'll help you diagnose the issue a little better.
In order to create the client with a path to the credentials file, you need to import google.golang.org/api/option, and create the client with the WithCredentialsFile option. Note in the docs that the client can be created with additional options:
func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error)
A somewhat more complete example on how to create a client with options would be the following (apply the required parts to your current code as needed):
package main
import (
"cloud.google.com/go/translate"
"context"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
client, err := translate.NewClient(ctx, option.WithCredentialsFile("/path/to/your/file"))
if err != nil {
// TODO: handle error.
}
// Use the client.
// Close the client when finished.
if err := client.Close(); err != nil {
// TODO: handle error.
}
}
(This is just a copy of the example in the docs with the additional option included.)
I solved the issue. I downloaded "google cloud shell SDK" and I used "gcloud auth application-default login" code. SDK provides a JSON file and I replaced it with new JSON file.
I do not recommend cloud.google.com/translate/docs/setup instructions. Direct use Google cloud SDK.
Related
I was looking for ways to set or update instance Labels on GCP Compute Instance and labelFingerprint confused me.
then I figure it out and I'm putting the code in the answer section.
I used this simple code to add new labels to GCP instances.
package main
import (
"context"
"log"
"os"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
)
func main() {
addLabelToGCPInstances()
}
func addLabelToGCPInstances() error {
// You can pass these as args
project := "Your GCP Project ID"
zone := "europe-west2-a"
instance := "milad-test-instance"
prodLablesMap := map[string]string{
"production": "true",
"environment": "production",
}
ctx := context.Background()
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "gke.json")
c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
if err != nil {
return err
}
computeService, err := compute.New(c)
if err != nil {
return err
}
respInstance, err := computeService.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
rb := &compute.InstancesSetLabelsRequest{
Labels: prodLablesMap,
LabelFingerprint: respInstance.LabelFingerprint,
}
respLabels, err := computeService.Instances.SetLabels(project, zone, instance, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
_ = respLabels
return err
}
This is just an example you can work around and do more error handling and etc.
This code is on the basis of golang.org/x/oauth2 example test. I am trying to get instance information from Google Compute Engine using Go client. Do I have to use oauth2 authentication? There is a generated link after Visit the URL for the auth dialog:
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=xxx&redirect_uri=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&state=state
and it redirect to https://www.googleapis.com/auth/compute which shows a 'compute'.
How do I achieve automatic authentication?
package main
import (
"context"
"fmt"
"log"
"golang.org/x/oauth2"
"google.golang.org/api/compute/v1"
)
type GCE struct {
*compute.Service
}
var ctx = context.Background()
func initGCE() *GCE {
conf := &oauth2.Config{
ClientID: "xxx",
ClientSecret: "xxx",
Scopes: []string{compute.ComputeScope},
Endpoint: oauth2.Endpoint{
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://accounts.google.com/o/oauth2/auth",
},
RedirectURL: "https://www.googleapis.com/auth/compute",
}
url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline)
fmt.Printf("Visit the URL for the auth dialog: %v", url)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatal(err)
}
tok, err := conf.Exchange(ctx, code)
if err != nil {
log.Fatal(err)
}
service, err := compute.New(conf.Client(ctx, tok))
if err != nil {
log.Fatal(err)
}
return &GCE{service}
}
func (g *GCE) Instance() {
project := "arctic-cyclist-189707"
zone := "us-east1-b"
instance := "centos7"
resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
fmt.Println(err)
return
} else {
fmt.Printf("%#v\n", resp)
}
}
Solved by using code example
https://cloud.google.com/compute/docs/reference/latest/instances/get#examples
just set "GOOGLE_APPLICATION_CREDENTIALS" environment varibles as google.DefaultClient() requires.
package main
import (
"context"
"fmt"
"log"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
)
type GCE struct {
*compute.Service
}
var ctx = context.Background()
func initGCE() *GCE {
c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
if err != nil {
log.Fatal(err)
}
computeService, err := compute.New(c)
if err != nil {
log.Fatal(err)
}
return &GCE{computeService}
}
func (g *GCE) Instance(project, zone, instance string) {
resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", resp)
}
Thanks for your reply.
I'm trying to follow the Google Sheets API quickstart here:
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
(scroll down to "Examples" then click "GO")
This is how I tried to update a spreadsheet:
package main
// BEFORE RUNNING:
// ---------------
// 1. If not already done, enable the Google Sheets API
// and check the quota for your project at
// https://console.developers.google.com/apis/api/sheets
// 2. Install and update the Go dependencies by running `go get -u` in the
// project directory.
import (
"errors"
"fmt"
"log"
"net/http"
"golang.org/x/net/context"
"google.golang.org/api/sheets/v4"
)
func main() {
ctx := context.Background()
c, err := getClient(ctx)
if err != nil {
log.Fatal(err)
}
sheetsService, err := sheets.New(c)
if err != nil {
log.Fatal(err)
}
// The ID of the spreadsheet to update.
spreadsheetId := "1diQ943LGMDNkbCRGG4VqgKZdzyanCtT--V8o7r6kCR0"
var jsonPayloadVar []string
monthVar := "Apr"
thisCellVar := "A26"
thisLinkVar := "http://test.url"
jsonRackNumberVar := "\"RACKNUM01\""
jsonPayloadVar = append(jsonPayloadVar, fmt.Sprintf("(\"range\": \"%v!%v\", \"values\": [[\"%v,%v)\"]]),", monthVar, thisCellVar, thisLinkVar, jsonRackNumberVar))
rb := &sheets.BatchUpdateValuesRequest{"ValueInputOption": "USER_ENTERED", "data": jsonPayloadVar}
resp, err := sheetsService.Spreadsheets.Values.BatchUpdate(spreadsheetId, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", resp)
}
func getClient(ctx context.Context) (*http.Client, error) {
// https://developers.google.com/sheets/quickstart/go#step_3_set_up_the_sample
//
// Authorize using the following scopes:
// sheets.DriveScope
// sheets.DriveFileScope
sheets.SpreadsheetsScope
return nil, errors.New("not implemented")
}
Output:
hello.go:43: invalid field name "ValueInputOption" in struct initializer
hello.go:43: invalid field name "data" in struct initializer
hello.go:58: sheets.SpreadsheetsScope evaluated but not used
There are 2 things that aren't working:
It's not obvious how to enter the fields into variable rb
I need to use sheets.SpreadsheetsScope
Can anyone provide a working example that does a BatchUpdate?
References:
This article shows how to do an update that is not a BatchUpdate: Golang google sheets API V4 - Write/Update example?
Google's API reference - see the ValueInputOption section starting at line 1437: https://github.com/google/google-api-go-client/blob/master/sheets/v4/sheets-gen.go
This article shows how to do a BatchUpdate in Java: Write data to Google Sheet using Google Sheet API V4 - Java Sample Code
How about the following sample script? This is a simple sample script for updating sheet on Spreadsheet. So if you want to do various update, please modify it. The detail of parameters for spreadsheets.values.batchUpdate is here.
Flow :
At first, in ordet to use the link in your question, please use Go Quickstart. In my sample script, the script was made using the Quickstart.
The flow to use this sample script is as follows.
For Go Quickstart, please do Step 1 and Step 2.
Please put client_secret.json to the same directory with my sample script.
Copy and paste my sample script, and create it as new script file.
Run the script.
When Go to the following link in your browser then type the authorization code: is shown on your terminal, please copy the URL and paste to your browser. And then, please authorize and get code.
Put the code to the terminal.
When Done. is displayed, it means that the update of spreadsheet is done.
Request body :
For Spreadsheets.Values.BatchUpdate, BatchUpdateValuesRequest is required as one of parameters. In this case, the range, values and so on that you want to update are included in BatchUpdateValuesRequest. The detail information of this BatchUpdateValuesRequest can be seen at godoc. When it sees BatchUpdateValuesRequest, Data []*ValueRange can be seen. Here, please be carefull that Data is []*ValueRange. Also ValueRange can be seen at godoc. You can see MajorDimension, Range and Values in ValueRange.
When above infomation is reflected to the script, the script can be modified as follows.
Sample script :
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/sheets/v4"
)
// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
cacheFile := "./go-quickstart.json"
tok, err := tokenFromFile(cacheFile)
if err != nil {
tok = getTokenFromWeb(config)
saveToken(cacheFile, tok)
}
return config.Client(ctx, tok)
}
// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
fmt.Printf("Go to the following link in your browser then type the "+
"authorization code: \n%v\n", authURL)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}
return tok
}
// tokenFromFile retrieves a Token from a given file path.
// It returns the retrieved Token and any read error encountered.
func tokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
t := &oauth2.Token{}
err = json.NewDecoder(f).Decode(t)
defer f.Close()
return t, err
}
func saveToken(file string, token *oauth2.Token) {
fmt.Printf("Saving credential file to: %s\n", file)
f, err := os.Create(file)
if err != nil {
log.Fatalf("Unable to cache oauth token: %v", err)
}
defer f.Close()
json.NewEncoder(f).Encode(token)
}
type body struct {
Data struct {
Range string `json:"range"`
Values [][]string `json:"values"`
} `json:"data"`
ValueInputOption string `json:"valueInputOption"`
}
func main() {
ctx := context.Background()
b, err := ioutil.ReadFile("client_secret.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets")
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(ctx, config)
sheetsService, err := sheets.New(client)
if err != nil {
log.Fatalf("Unable to retrieve Sheets Client %v", err)
}
spreadsheetId := "### spreadsheet ID ###"
rangeData := "sheet1!A1:B3"
values := [][]interface{}{{"sample_A1", "sample_B1"}, {"sample_A2", "sample_B2"}, {"sample_A3", "sample_A3"}}
rb := &sheets.BatchUpdateValuesRequest{
ValueInputOption: "USER_ENTERED",
}
rb.Data = append(rb.Data, &sheets.ValueRange{
Range: rangeData,
Values: values,
})
_, err = sheetsService.Spreadsheets.Values.BatchUpdate(spreadsheetId, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
fmt.Println("Done.")
}
Result :
References :
The detail infomation of spreadsheets.values.batchUpdate is here.
The detail infomation of Go Quickstart is here.
The detail infomation of BatchUpdateValuesRequest is here.
The detail infomation of ValueRange is here.
If I misunderstand your question, I'm sorry.
Trying to write a simple three column table ([][]string) with Go, but can't.
The quick start guide is very nice, I now can read sheets, but there no any example of how to write data to a sheet, maybe it is trivial, but not for me it seems.
The Golang library for my brains is just too complicated to figure out.
And there not a single example I could google...
This C# example very looks close, but I am not sure I clearly understand C#
Well after some tryouts, there is an answer. Everything is same as in https://developers.google.com/sheets/quickstart/go Just changes in the main function
func write() {
ctx := context.Background()
b, err := ioutil.ReadFile("./Google_Sheets_API_Quickstart/client_secret.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-go-quickstart.json
config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets")
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(ctx, config)
srv, err := sheets.New(client)
if err != nil {
log.Fatalf("Unable to retrieve Sheets Client %v", err)
}
spreadsheetId := "YOUR SPREADSHEET ID"
writeRange := "A1"
var vr sheets.ValueRange
myval := []interface{}{"One", "Two", "Three"}
vr.Values = append(vr.Values, myval)
_, err = srv.Spreadsheets.Values.Update(spreadsheetId, writeRange, &vr).ValueInputOption("RAW").Do()
if err != nil {
log.Fatalf("Unable to retrieve data from sheet. %v", err)
}
}
Well if you are looking for Service Account based authentication, then the following worked for me.
Download the client secret file for service account from https://console.developers.google.com
import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/api/option"
"google.golang.org/api/sheets/v4"
"log"
)
const (
client_secret_path = "./credentials/client_secret.json"
)
func NewSpreadsheetService() (*SpreadsheetService, error) {
// Service account based oauth2 two legged integration
ctx := context.Background()
srv, err := sheets.NewService(ctx, option.WithCredentialsFile(client_secret_path), option.WithScopes(sheets.SpreadsheetsScope))
if err != nil {
log.Fatalf("Unable to retrieve Sheets Client %v", err)
}
c := &SpreadsheetService{
service: srv,
}
return c, nil
}
func (s *SpreadsheetService) WriteToSpreadsheet(object *SpreadsheetPushRequest) error {
var vr sheets.ValueRange
vr.Values = append(vr.Values, object.Values)
res, err := s.service.Spreadsheets.Values.Append(object.SpreadsheetId, object.Range, &vr).ValueInputOption("RAW").Do()
fmt.Println("spreadsheet push ", res)
if err != nil {
fmt.Println("Unable to update data to sheet ", err)
}
return err
}
type SpreadsheetPushRequest struct {
SpreadsheetId string `json:"spreadsheet_id"`
Range string `json:"range"`
Values []interface{} `json:"values"`
}
change the scope in the quickstart example from spreadsheets.readonly to spreadsheets for r/w access
here is the write snippet:
writeRange := "A1" // or "sheet1:A1" if you have a different sheet
values := []interface{}{"It worked!"}
var vr sheets.ValueRange
vr.Values = append(vr.Values,values
_, err = srv.Spreadsheets.Values.Update(spreadsheetId,writeRange,&vr).ValueInputOption("RAW").Do()
and that should work:
// datastore1
package main
import (
"fmt"
"io/ioutil"
"log"
"time"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/cloud"
"google.golang.org/cloud/datastore"
)
const (
// ScopeDatastore grants permissions to view and/or manage datastore entities
copeDatastore = "https://www.googleapis.com/auth/datastore"
// ScopeUserEmail grants permission to view the user's email address.
// It is required to access the datastore.
ScopeUserEmail = "https://www.googleapis.com/auth/userinfo.email"
)
type ehrEntity struct {
email *datastore.Key
firstname string
lastname string
address string
age int8
dateofbirth time.Time
sex bool
}
func getCtx() *datastore.Client {
// Initialize an authorized transport with Google Developers Console
// JSON key. Read the google package examples to learn more about
// different authorization flows you can use.
// http://godoc.org/golang.org/x/oauth2/google
jsonKey, err := ioutil.ReadFile("filename.json")
opts, err := google.JWTConfigFromJSON(
jsonKey,
datastore.ScopeDatastore,
datastore.ScopeUserEmail,
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx", cloud.WithTokenSource(opts.TokenSource(ctx)))
if err != nil {
log.Fatal(err)
}
// Use the context (see other examples)
return client
}
func ExampleGet() {
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx")
if err != nil {
log.Fatal(err)
}
key := datastore.NewKey(ctx, "User", "tluu#abc.com", 0, nil)
ehr := ehrEntity{
nil,
"tri",
"luu",
"addr1",
20,
time.Date(2009, time.January, 10, 23, 0, 0, 0, time.UTC),
false}
if err := client.Get(ctx, key, ehr); err != nil {
log.Fatal(err)
}
}
func main() {
getCtx()
fmt.Println("Pass authentication")
ExampleGet()
}
When I run go file, It return error follow:
Pass authentication (Pass getCtx() function).
Error in ExampleGet()
May be at
ctx := context.Background()
client, err := datastore.NewClient(ctx, "xxxx")
if err != nil {
log.Fatal(err)
}
Error:
2016/01/09 22:08:43 Post https://www.googleapis.com/datastore/v1beta2/datasets/xxxx/lookup: oauth2: cannot fetch token: 400 Bad Request
Response: {
"error" : "invalid_grant"
}
How to resolve this error?
This appears to have worked for me.
If you are on linux try the following:
1. apt-get update
2. apt-get install ntp
3. /etc/init.d/ntp restart