Repository: feast-dev/feast

Issue:
Support for BQ Datasets not in US
## Expected Behavior 
 Currently Feast is assuming the location of my datasets is always in US as this is the current default location for the BQ Client. 
It would be good to have the possibility to specify the location somewhere

## Current Behavior

```
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/feast/infra/offline_stores/bigquery.py", line 239, in to_df
    df = self.client.query(self.query).to_dataframe(create_bqstorage_client=True)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/google/cloud/bigquery/job/query.py", line 1340, in to_dataframe
    query_result = wait_for_query(self, progress_bar_type)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/google/cloud/bigquery/_tqdm_helpers.py", line 65, in wait_for_query
    return query_job.result()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/google/cloud/bigquery/job/query.py", line 1172, in result
    super(QueryJob, self).result(retry=retry, timeout=timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/google/cloud/bigquery/job/base.py", line 679, in result
    return super(_AsyncJob, self).result(timeout=timeout, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/google/api_core/future/polling.py", line 134, in result
    raise self._exception
google.api_core.exceptions.NotFound: 404 Not found: Dataset project_id:test_feast was not found in location US
```



Discussion:
You should be able to set the `dataset` name manually as part of your bigquery configuration (to a pre-existing dataset). Or would you like to **not** set the dataset name but only the region?
@woop  thanks for your quick response! I am able to set manually my table reference as part Big query source configuration. When I do `feast apply` everything works well but when I try to store some data in that table I receive a message saying that the dataset can't be found in US. So yes responding to your question I would like to set the location for a certain table (and the relative dataset)
> @woop thanks for your quick response! I am able to set manually my table reference as part Big query source configuration. When I do `feast apply` everything works well but when I try to store some data in that table I receive a message saying that the dataset can't be found in US. So yes responding to your question I would like to set the location for a certain table (and the relative dataset)

@elia-secchi can you try to delete that dataset, recreate it manually in the right region, and then configure Feast to use your dataset? I am assuming you are still using the automatically generated on (which defaults to the US).
Separately we can also add a configuration option for this, but I the above is a workaround for the time being.
@woop thanks for the help, the workaround you suggested solved the issue I was having!
@woop I set the BQ dataset to "asia-northeast3" region, but it doesn't work.
Is there any way to manually set the region?

Resolving patch:
diff --git a/sdk/python/feast/infra/offline_stores/bigquery.py b/sdk/python/feast/infra/offline_stores/bigquery.py
--- a/sdk/python/feast/infra/offline_stores/bigquery.py
+++ b/sdk/python/feast/infra/offline_stores/bigquery.py
@@ -52,6 +52,13 @@ class BigQueryOfflineStoreConfig(FeastConfigBaseModel):
     project_id: Optional[StrictStr] = None
     """ (optional) GCP project name used for the BigQuery offline store """
 
+    location: Optional[StrictStr] = None
+    """ (optional) GCP location name used for the BigQuery offline store.
+    Examples of location names include ``US``, ``EU``, ``us-central1``, ``us-west4``.
+    If a location is not specified, the location defaults to the ``US`` multi-regional location.
+    For more information on BigQuery data locations see: https://cloud.google.com/bigquery/docs/locations
+    """
+
 
 class BigQueryOfflineStore(OfflineStore):
     @staticmethod
@@ -79,7 +86,10 @@ def pull_latest_from_table_or_query(
         timestamp_desc_string = " DESC, ".join(timestamps) + " DESC"
         field_string = ", ".join(join_key_columns + feature_name_columns + timestamps)
 
-        client = _get_bigquery_client(project=config.offline_store.project_id)
+        client = _get_bigquery_client(
+            project=config.offline_store.project_id,
+            location=config.offline_store.location,
+        )
         query = f"""
             SELECT
                 {field_string}
@@ -115,7 +125,10 @@ def get_historical_features(
         # TODO: Add entity_df validation in order to fail before interacting with BigQuery
         assert isinstance(config.offline_store, BigQueryOfflineStoreConfig)
 
-        client = _get_bigquery_client(project=config.offline_store.project_id)
+        client = _get_bigquery_client(
+            project=config.offline_store.project_id,
+            location=config.offline_store.location,
+        )
 
         assert isinstance(config.offline_store, BigQueryOfflineStoreConfig)
 
@@ -367,9 +380,9 @@ def _upload_entity_df_and_get_entity_schema(
     return entity_schema
 
 
-def _get_bigquery_client(project: Optional[str] = None):
+def _get_bigquery_client(project: Optional[str] = None, location: Optional[str] = None):
     try:
-        client = bigquery.Client(project=project)
+        client = bigquery.Client(project=project, location=location)
     except DefaultCredentialsError as e:
         raise FeastProviderLoginError(
             str(e)


Test patch: