Compare commits

...

1 Commits

Author SHA1 Message Date
google-labs-jules[bot]
5e25d82b37 feat: Introduce application_name configuration to BigQuery source 2025-09-17 02:38:18 +00:00
4 changed files with 41 additions and 9 deletions

View File

@@ -109,6 +109,7 @@ sources:
my-bigquery-source:
kind: "bigquery"
project: "my-project-id"
# application_name: "my-app" # Optional: The name of the application using the BigQuery source.
# location: "US" # Optional: Specifies the location for query jobs.
# allowedDatasets: # Optional: Restricts tool access to a specific list of datasets.
# - "my_dataset_1"
@@ -131,10 +132,11 @@ sources:
## Reference
| **field** | **type** | **required** | **description** |
|-----------------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kind | string | true | Must be "bigquery". |
| project | string | true | Id of the Google Cloud project to use for billing and as the default project for BigQuery resources. |
| location | string | false | Specifies the location (e.g., 'us', 'asia-northeast1') in which to run the query job. This location must match the location of any tables referenced in the query. Defaults to the table's location or 'US' if the location cannot be determined. [Learn More](https://cloud.google.com/bigquery/docs/locations) |
| allowedDatasets | []string | false | An optional list of dataset IDs that tools using this source are allowed to access. If provided, any tool operation attempting to access a dataset not in this list will be rejected. To enforce this, two types of operations are also disallowed: 1) Dataset-level operations (e.g., `CREATE SCHEMA`), and 2) operations where table access cannot be statically analyzed (e.g., `EXECUTE IMMEDIATE`, `CREATE PROCEDURE`). If a single dataset is provided, it will be treated as the default for prebuilt tools. |
| useClientOAuth | bool | false | If true, forwards the client's OAuth access token from the "Authorization" header to downstream queries. |
| **field** | **type** | **required** | **description** |
|--------------------|:--------:|:------------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| kind | string | true | Must be "bigquery". |
| project | string | true | Id of the Google Cloud project to use for billing and as the default project for BigQuery resources. |
| location | string | false | Specifies the location (e.g., 'us', 'asia-northeast1') in which to run the query job. This location must match the location of any tables referenced in the query. Defaults to the table's location or 'US' if the location cannot be determined. [Learn More](https://cloud.google.com/bigquery/docs/locations) |
| application_name | string | false | The name of the application using the BigQuery source. This is propagated as the user_agent in the BigQuery client. |
| allowedDatasets | []string | false | An optional list of dataset IDs that tools using this source are allowed to access. If provided, any tool operation attempting to access a dataset not in this list will be rejected. To enforce this, two types of operations are also disallowed: 1) Dataset-level operations (e.g., `CREATE SCHEMA`), and 2) operations where table access cannot be statically analyzed (e.g., `EXECUTE IMMEDIATE`, `CREATE PROCEDURE`). If a single dataset is provided, it will be treated as the default for prebuilt tools. |
| useClientOAuth | bool | false | If true, forwards the client's OAuth access token from the "Authorization" header to downstream queries. |

View File

@@ -17,6 +17,7 @@ sources:
kind: "bigquery"
project: ${BIGQUERY_PROJECT}
location: ${BIGQUERY_LOCATION:}
application_name: ${BIGQUERY_APPLICATION_NAME:}
useClientOAuth: ${BIGQUERY_USE_CLIENT_OAUTH:false}
tools:

View File

@@ -59,6 +59,7 @@ type Config struct {
Kind string `yaml:"kind" validate:"required"`
Project string `yaml:"project" validate:"required"`
Location string `yaml:"location"`
ApplicationName string `yaml:"application_name,omitempty"`
AllowedDatasets []string `yaml:"allowedDatasets"`
UseClientOAuth bool `yaml:"useClientOAuth"`
}
@@ -76,13 +77,13 @@ func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.So
var err error
if r.UseClientOAuth {
clientCreator, err = newBigQueryClientCreator(ctx, tracer, r.Project, r.Location, r.Name)
clientCreator, err = newBigQueryClientCreator(ctx, tracer, r.Project, r.Location, r.Name, r.ApplicationName)
if err != nil {
return nil, fmt.Errorf("error constructing client creator: %w", err)
}
} else {
// Initializes a BigQuery Google SQL source
client, restService, tokenSource, err = initBigQueryConnection(ctx, tracer, r.Name, r.Project, r.Location)
client, restService, tokenSource, err = initBigQueryConnection(ctx, tracer, r.Name, r.Project, r.Location, r.ApplicationName)
if err != nil {
return nil, fmt.Errorf("error creating client from ADC: %w", err)
}
@@ -219,6 +220,7 @@ func initBigQueryConnection(
name string,
project string,
location string,
applicationName string,
) (*bigqueryapi.Client, *bigqueryrestapi.Service, oauth2.TokenSource, error) {
ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name)
defer span.End()
@@ -232,6 +234,9 @@ func initBigQueryConnection(
if err != nil {
return nil, nil, nil, err
}
if applicationName != "" {
userAgent = userAgent + " " + applicationName
}
// Initialize the high-level BigQuery client
client, err := bigqueryapi.NewClient(ctx, project, option.WithUserAgent(userAgent), option.WithCredentials(cred))
@@ -297,11 +302,15 @@ func newBigQueryClientCreator(
project string,
location string,
name string,
applicationName string,
) (func(string, bool) (*bigqueryapi.Client, *bigqueryrestapi.Service, error), error) {
userAgent, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, err
}
if applicationName != "" {
userAgent = userAgent + " " + applicationName
}
return func(tokenString string, wantRestService bool) (*bigqueryapi.Client, *bigqueryrestapi.Service, error) {
return initBigQueryConnectionWithOAuthToken(ctx, tracer, project, location, name, userAgent, tokenString, wantRestService)

View File

@@ -90,6 +90,26 @@ func TestParseFromYamlBigQuery(t *testing.T) {
},
},
},
{
desc: "with application name",
in: `
sources:
my-instance:
kind: bigquery
project: my-project
location: us
application_name: my-app
`,
want: server.SourceConfigs{
"my-instance": bigquery.Config{
Name: "my-instance",
Kind: bigquery.SourceKind,
Project: "my-project",
Location: "us",
ApplicationName: "my-app",
},
},
},
}
for _, tc := range tcs {
t.Run(tc.desc, func(t *testing.T) {