diff --git a/samples/account_summaries_list.py b/samples/account_summaries_list.py new file mode 100644 index 00000000..cb608168 --- /dev/null +++ b/samples/account_summaries_list.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which prints summaries of +all accounts accessible by the caller. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accountSummaries/list +for more information. +""" +# [START analyticsadmin_account_summaries_list] +from google.analytics.admin import AnalyticsAdminServiceClient + + +def list_account_summaries(): + """Returns summaries of all accounts accessible by the caller.""" + client = AnalyticsAdminServiceClient() + results = client.list_account_summaries() + + print("Result:") + for account_summary in results: + print("-- Account --") + print(f"Resource name: {account_summary.name}") + print(f"Account name: {account_summary.account}") + print(f"Display name: {account_summary.display_name}") + print() + for property_summary in account_summary.property_summaries: + print("-- Property --") + print(f"Property resource name: {property_summary.property}") + print(f"Property display name: {property_summary.display_name}") + print() + + +# [END analyticsadmin_account_summaries_list] + + +if __name__ == "__main__": + list_account_summaries() diff --git a/samples/account_summaries_list_test.py b/samples/account_summaries_list_test.py new file mode 100644 index 00000000..d97ef6dc --- /dev/null +++ b/samples/account_summaries_list_test.py @@ -0,0 +1,21 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import account_summaries_list + + +def test_account_summaries_list(capsys): + account_summaries_list.list_account_summaries() + out, _ = capsys.readouterr() + assert "Result" in out diff --git a/samples/accounts_delete.py b/samples/accounts_delete.py new file mode 100644 index 00000000..7c6f7afa --- /dev/null +++ b/samples/accounts_delete.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which deletes a Google +Analytics account. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/delete +for more information. +""" +# [START analyticsadmin_accounts_delete] +from google.analytics.admin import AnalyticsAdminServiceClient + + +def run_sample(): + """Runs the sample.""" + + # !!! ATTENTION !!! + # Running this sample may change/delete your Google Analytics account + # configuration. Make sure to not use the Google Analytics account ID from + # your production environment below. + + # TODO(developer): Replace this variable with your Google Analytics + # account ID (e.g. "123456") before running the sample. + account_id = "YOUR-GA-ACCOUNT-ID" + delete_account(account_id) + + +def delete_account(account_id: str): + """Deletes the Google Analytics account.""" + client = AnalyticsAdminServiceClient() + client.delete_account(name=f"accounts/{account_id}") + print("Account deleted") + + +# [END analyticsadmin_accounts_delete] + + +if __name__ == "__main__": + run_sample() diff --git a/samples/accounts_delete_test.py b/samples/accounts_delete_test.py new file mode 100644 index 00000000..0458fefc --- /dev/null +++ b/samples/accounts_delete_test.py @@ -0,0 +1,28 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +import accounts_delete + + +FAKE_ACCOUNT_ID = "1" + + +def test_accounts_delete(): + # This test ensures that the call is valid and reaches the server. No + # account is being deleted during the test as it is not trivial to + # provision a new account for testing. + with pytest.raises(Exception, match="403 The caller does not have permission"): + accounts_delete.delete_account(FAKE_ACCOUNT_ID) diff --git a/samples/accounts_get.py b/samples/accounts_get.py new file mode 100644 index 00000000..d7cbf927 --- /dev/null +++ b/samples/accounts_get.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which prints the Google +Analytics account data. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/get +for more information. +""" +# [START analyticsadmin_accounts_get] +from google.analytics.admin import AnalyticsAdminServiceClient + + +def run_sample(): + """Runs the sample.""" + # TODO(developer): Replace this variable with your Google Analytics + # account ID (e.g. "123456") before running the sample. + account_id = "YOUR-GA-ACCOUNT-ID" + get_account(account_id) + + +def get_account(account_id: str): + """Retrieves the Google Analytics account data.""" + client = AnalyticsAdminServiceClient() + account = client.get_account(name=f"accounts/{account_id}") + + print("Result:") + print_account(account) + + +def print_account(account: str): + """Prints account data.""" + print(f"Resource name: {account.name}") + print(f"Display name: {account.display_name}") + print(f"Region code: {account.region_code}") + print(f"Create time: {account.create_time}") + print(f"Update time: {account.update_time}") + + +# [END analyticsadmin_accounts_get] + + +if __name__ == "__main__": + run_sample() diff --git a/samples/accounts_get_data_sharing_settings.py b/samples/accounts_get_data_sharing_settings.py new file mode 100644 index 00000000..66a8ef29 --- /dev/null +++ b/samples/accounts_get_data_sharing_settings.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which prints the data sharing +settings on an account. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/getDataSharingSettings +for more information. +""" +# [START analyticsadmin_accounts_get_data_sharing_settings] +from google.analytics.admin import AnalyticsAdminServiceClient + + +def run_sample(): + """Runs the sample.""" + + # TODO(developer): Replace this variable with your Google Analytics + # account ID (e.g. "123456") before running the sample. + account_id = "YOUR-GA-ACCOUNT-ID" + get_data_sharing_settings(account_id) + + +def get_data_sharing_settings(account_id: str): + """Gets data sharing settings on an account.""" + client = AnalyticsAdminServiceClient() + data_sharing_settings = client.get_data_sharing_settings( + name=f"accounts/{account_id}/dataSharingSettings" + ) + + print("Result:") + print(f"Resource name: {data_sharing_settings.name}") + print( + f"Sharing with Google support enabled: {data_sharing_settings.sharing_with_google_support_enabled}" + ) + print( + f"Sharing with Google assigned sales enabled: {data_sharing_settings.sharing_with_google_assigned_sales_enabled}" + ) + print( + f"Sharing with others enabled: {data_sharing_settings.sharing_with_others_enabled}" + ) + + +# [END analyticsadmin_accounts_get_data_sharing_settings] + + +if __name__ == "__main__": + run_sample() diff --git a/samples/accounts_get_data_sharing_settings_test.py b/samples/accounts_get_data_sharing_settings_test.py new file mode 100644 index 00000000..6232fc72 --- /dev/null +++ b/samples/accounts_get_data_sharing_settings_test.py @@ -0,0 +1,25 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +import accounts_get_data_sharing_settings + +TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID") + + +def test_accounts_get_data_sharing_settings(capsys): + accounts_get_data_sharing_settings.get_data_sharing_settings(TEST_ACCOUNT_ID) + out, _ = capsys.readouterr() + assert "Result" in out diff --git a/samples/accounts_get_test.py b/samples/accounts_get_test.py new file mode 100644 index 00000000..5c0c1313 --- /dev/null +++ b/samples/accounts_get_test.py @@ -0,0 +1,25 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +import accounts_get + +TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID") + + +def test_accounts_get(capsys): + accounts_get.get_account(TEST_ACCOUNT_ID) + out, _ = capsys.readouterr() + assert "Result" in out diff --git a/samples/accounts_list.py b/samples/accounts_list.py new file mode 100644 index 00000000..f69869e4 --- /dev/null +++ b/samples/accounts_list.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which prints the Google +Analytics accounts available to the current user. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/list +for more information. +""" +# [START analyticsadmin_accounts_list] +from google.analytics.admin import AnalyticsAdminServiceClient + +from accounts_get import print_account + + +def list_accounts(): + """Lists the Google Analytics accounts available to the current user.""" + client = AnalyticsAdminServiceClient() + results = client.list_accounts() + + print("Result:") + for account in results: + print_account(account) + + +# [END analyticsadmin_accounts_list] + + +if __name__ == "__main__": + list_accounts() diff --git a/samples/accounts_list_test.py b/samples/accounts_list_test.py new file mode 100644 index 00000000..379c73b3 --- /dev/null +++ b/samples/accounts_list_test.py @@ -0,0 +1,21 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import accounts_list + + +def test_accounts_list(capsys): + accounts_list.list_accounts() + out, _ = capsys.readouterr() + assert "Result" in out diff --git a/samples/accounts_provision_account_ticket.py b/samples/accounts_provision_account_ticket.py new file mode 100644 index 00000000..3a574224 --- /dev/null +++ b/samples/accounts_provision_account_ticket.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which provisions the Google +Analytics account creation ticket and prints the Terms of Service link that +can be used by an end user to complete the account creation flow. + +This sample invokes the provision_account_ticket() method of the Google +Analytics Admin API to start the Google Analytics account creation +process for a user. This method returns an account ticket which shall be used +to generate the Terms Of Service url that an end user should visit in order +to accept the Terms and complete the account creation flow. + +You have to authenticate as an end user in order to run this sample. Only +the authenticated user will be able to use the Terms of Service url generated +as part of the account provisioning flow. + +To authenticate as an end user prior to running this sample, use the +gcloud tool: + + gcloud auth application-default login --scopes=https://www.googleapis.com/auth/analytics.edit --client-id-file=PATH_TO_YOUR_CLIENT_SECRET_JSON + + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/provisionAccountTicket +for more information. +""" +# [START analyticsadmin_accounts_provision_account_ticket] +from google.analytics.admin import AnalyticsAdminServiceClient +from google.analytics.admin_v1alpha.types import Account +from google.analytics.admin_v1alpha.types import ProvisionAccountTicketRequest + + +def run_sample(): + """Runs the sample.""" + + # !!! ATTENTION !!! + # Running this sample may change/delete your Google Analytics account + # configuration. Make sure to not use the Google Analytics account ID from + # your production environment below. + + # TODO(developer): Replace this variable with a redirect URI where the user + # will be sent after accepting Terms of Service. Must be configured in + # Developers Console as a Redirect URI + redirect_uri = "YOUR-REDIRECT-URI" + + provision_account_ticket(redirect_uri) + + +def provision_account_ticket(redirect_uri: str): + """Provisions the Google Analytics account creation ticket.""" + client = AnalyticsAdminServiceClient() + response = client.provision_account_ticket( + ProvisionAccountTicketRequest( + account=Account(display_name="Test Account", region_code="US"), + redirect_uri=redirect_uri, + ) + ) + + print("Result:") + print(f"Account ticket id: {response.account_ticket_id}") + print( + f"You can now open the following URL to complete the account creation:" + f"https://analytics.google.com/analytics/web/?provisioningSignup=false#/termsofservice/{response.account_ticket_id}" + ) + print() + print( + "Attention: make sure your browser is signed in to the same user " + "account that was used to provision the ticket." + ) + + +# [END analyticsadmin_accounts_provision_account_ticket] + + +if __name__ == "__main__": + run_sample() diff --git a/samples/accounts_provision_account_ticket_test.py b/samples/accounts_provision_account_ticket_test.py new file mode 100644 index 00000000..e08f9402 --- /dev/null +++ b/samples/accounts_provision_account_ticket_test.py @@ -0,0 +1,24 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import accounts_provision_account_ticket + + +TEST_REDIRECT_URL = "https://www.google.com" + + +def test_accounts_provision_account_ticket(capsys): + accounts_provision_account_ticket.provision_account_ticket(TEST_REDIRECT_URL) + out, _ = capsys.readouterr() + assert "Result" in out diff --git a/samples/accounts_update.py b/samples/accounts_update.py new file mode 100644 index 00000000..e3ae56ed --- /dev/null +++ b/samples/accounts_update.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Google Analytics Admin API sample application which updates the Google +Analytics account. + +See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/update +for more information. +""" +# [START analyticsadmin_accounts_update] +from google.analytics.admin import AnalyticsAdminServiceClient +from google.analytics.admin_v1alpha.types import Account +from google.protobuf.field_mask_pb2 import FieldMask + +from accounts_get import print_account + + +def run_sample(): + """Runs the sample.""" + + # !!! ATTENTION !!! + # Running this sample may change/delete your Google Analytics account + # configuration. Make sure to not use the Google Analytics account ID from + # your production environment below. + + # TODO(developer): Replace this variable with your Google Analytics + # account ID (e.g. "123456") before running the sample. + account_id = "YOUR-GA-ACCOUNT-ID" + update_account(account_id) + + +def update_account(account_id: str): + """Updates the Google Analytics account.""" + client = AnalyticsAdminServiceClient() + # This call updates the display name and region code of the account, as + # indicated by the value of the `update_mask` field. + # The account to update is specified in the `name` field of the `Account` + # instance. + account = client.update_account( + account=Account( + name=f"accounts/{account_id}", + display_name="This is a test account", + region_code="US", + ), + update_mask=FieldMask(paths=["display_name", "region_code"]), + ) + + print("Result:") + print_account(account) + + +# [END analyticsadmin_accounts_update] + + +if __name__ == "__main__": + run_sample() diff --git a/samples/accounts_update_test.py b/samples/accounts_update_test.py new file mode 100644 index 00000000..18c5f551 --- /dev/null +++ b/samples/accounts_update_test.py @@ -0,0 +1,27 @@ +# Copyright 2021 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +import accounts_update + + +FAKE_ACCOUNT_ID = "1" + + +def test_accounts_update(): + # This test ensures that the call is valid and reaches the server, even + # though the operation does not succeed due to permission error. + with pytest.raises(Exception, match="403 The caller does not have permission"): + accounts_update.update_account(FAKE_ACCOUNT_ID) diff --git a/samples/noxfile.py b/samples/noxfile.py new file mode 100644 index 00000000..804f957e --- /dev/null +++ b/samples/noxfile.py @@ -0,0 +1,252 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import os +from pathlib import Path +import sys +from typing import Callable, Dict, List, Optional + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + 'enforce_type_hints': False, + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars() -> Dict[str, str]: + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + ret['GCLOUD_PROJECT'] = os.environ[env_key] # deprecated + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir: str) -> List[str]: + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + if not TEST_CONFIG['enforce_type_hints']: + session.install("flake8", "flake8-import-order") + else: + session.install("flake8", "flake8-import-order", "flake8-annotations") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Black +# + +@nox.session +def blacken(session: nox.sessions.Session) -> None: + session.install("black") + python_files = [path for path in os.listdir(".") if path.endswith(".py")] + + session.run("black", *python_files) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None: + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + if os.path.exists("constraints.txt"): + session.install("-r", "requirements.txt", "-c", "constraints.txt") + else: + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + if os.path.exists("constraints-test.txt"): + session.install("-r", "requirements-test.txt", "-c", "constraints-test.txt") + else: + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session: nox.sessions.Session) -> None: + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root() -> Optional[str]: + """ Returns the root folder of the project. """ + # Get root of this repository. + # Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session: nox.sessions.Session, path: str) -> None: + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/samples/noxfile_config.py b/samples/noxfile_config.py new file mode 100644 index 00000000..b883a88e --- /dev/null +++ b/samples/noxfile_config.py @@ -0,0 +1,23 @@ +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": { + "GA_TEST_PROPERTY_ID": "222596558", + "GA_TEST_ACCOUNT_ID": "123", + "GA_TEST_USER_LINK_ID": "123", + "GA_TEST_ANDROID_APP_DATA_STREAM_ID": "123", + "GA_TEST_IOS_APP_DATA_STREAM_ID": "123", + "GA_TEST_WEB_DATA_STREAM_ID": "123", + }, +} diff --git a/samples/noxfile_config_test.py b/samples/noxfile_config_test.py new file mode 100644 index 00000000..e69de29b diff --git a/samples/requirements.txt b/samples/requirements.txt new file mode 100644 index 00000000..11e7e0fe --- /dev/null +++ b/samples/requirements.txt @@ -0,0 +1,2 @@ +google-analytics-admin==0.2.0 +google-auth-oauthlib==0.4.4 \ No newline at end of file