diff --git a/.github/renovate.json5 b/.github/renovate.json5
new file mode 100644
index 0000000..78bab54
--- /dev/null
+++ b/.github/renovate.json5
@@ -0,0 +1,39 @@
+// Based partially on https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/renovate.json
+{
+ "extends": [
+ // https://docs.renovatebot.com/presets-config/#configrecommended
+ "config:recommended",
+ "schedule:earlyMondays",
+ ":ignoreUnstable",
+ ],
+ // Apply label to PRs.
+ "labels": [
+ "dependencies",
+ ],
+ // https://docs.renovatebot.com/configuration-options/#minimumreleaseage
+ "minimumReleaseAge": "3 days",
+ "dependencyDashboardLabels": [
+ "type: process",
+ ],
+ "rebaseWhen": "behind-base-branch",
+ "semanticCommits": "enabled",
+ // Create PR for vulnerability alerts immediately.
+ "vulnerabilityAlerts": {
+ "labels": [
+ "security"
+ ],
+ "minimumReleaseAge": null
+ },
+ "packageRules": [
+ {
+ // Group Google Analytics packages together since they are part of
+ // the same release process.
+ "description": "Group Google Analytics API updates",
+ "matchPackageNames": [
+ "google-analytics-data",
+ "google-analytics-admin"
+ ],
+ "groupName": "Google Analytics APIs"
+ }
+ ]
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..63ee85d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,64 @@
+*.py[cod]
+*.sw[op]
+
+# C extensions
+*.so
+
+# Packages
+*.egg
+*.egg-info
+dist
+build
+eggs
+.eggs
+parts
+bin
+var
+sdist
+develop-eggs
+.installed.cfg
+lib
+lib64
+__pycache__
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.nox
+.cache
+.pytest_cache
+
+
+# Mac
+.DS_Store
+
+# JetBrains
+.idea
+
+# VS Code
+.vscode
+
+# emacs
+*~
+
+# Built documentation
+docs/_build
+docs.metadata
+
+# Virtual environment
+env/
+venv/
+
+# Test logs
+coverage.xml
+*sponge_log.xml
+
+# System test environment variables.
+system_tests/local_test_setup
+
+# Make sure a generated file isn't accidentally committed.
+pylintrc
+pylintrc.test
+
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..45720a9
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1 @@
+@googleanalytics/google-analytics
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..46b2a08
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,43 @@
+# Contributor Code of Conduct
+
+As contributors and maintainers of this project,
+and in the interest of fostering an open and welcoming community,
+we pledge to respect all people who contribute through reporting issues,
+posting feature requests, updating documentation,
+submitting pull requests or patches, and other activities.
+
+We are committed to making participation in this project
+a harassment-free experience for everyone,
+regardless of level of experience, gender, gender identity and expression,
+sexual orientation, disability, personal appearance,
+body size, race, ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery
+* Personal attacks
+* Trolling or insulting/derogatory comments
+* Public or private harassment
+* Publishing other's private information,
+such as physical or electronic
+addresses, without explicit permission
+* Other unethical or unprofessional conduct.
+
+Project maintainers have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct.
+By adopting this Code of Conduct,
+project maintainers commit themselves to fairly and consistently
+applying these principles to every aspect of managing this project.
+Project maintainers who do not follow or enforce the Code of Conduct
+may be permanently removed from the project team.
+
+This code of conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior
+may be reported by opening an issue
+or contacting one or more of the project maintainers.
+
+This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
+available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..9c18541
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,92 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement. You (or your employer) retain the copyright to your contribution;
+this simply gives us permission to use and redistribute your contributions as
+part of the project. Head over to to see
+your current agreements on file or to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
+## Community Guidelines
+
+This project follows [Google's Open Source Community
+Guidelines](https://opensource.google.com/conduct/).
+
+## Code Style
+
+All Python samples should follow the best practices defined in the [PEP 8 style
+guide](https://www.python.org/dev/peps/pep-0008/) and the [Google Python Style
+Guide](http://google.github.io/styleguide/pyguide.html). The automated linting
+process for Python samples uses [flake8](http://flake8.pycqa.org/en/latest/) to
+verify conformance to common Python coding standards, so the use of flake8 is
+recommended.
+
+If you prefer to use [pylint](https://www.pylint.org/), note that Python samples
+for this repo are not required to conform to pylint’s default settings outside
+the scope of PEP 8, such as the “too many arguments” or “too many local
+variables” warnings.
+
+The use of [Black](https://pypi.org/project/black/) to standardize code
+formatting and simplify diffs is recommended.
+
+The default noxfile defines a `blacken` session for convenience. If you have
+pyenv configured, you can check and format all files in `google-analytics-admin`
+or `google-analytics-data` using the following command:
+
+```sh
+nox -s lint blacken
+```
+
+## Running the tests
+
+1. Configure your environment and credentials as described in the
+ [README](README.md).
+2. Change into the directory of the project you want to test (either
+ `google-analytics-admin` or `google-analytics-data`).
+3. Configure environment variables required by tests using the following
+ commands:
+
+ ```sh
+ # These values are required by Admin and Data API samples tests.
+ export GOOGLE_CLOUD_PROJECT=
+ export GA_TEST_PROPERTY_ID=
+ # These values are only required by Admin API samples tests.
+ export GA_TEST_ACCOUNT_ID=
+ export GA_TEST_WEB_DATA_STREAM_ID=
+ export GA_TEST_WEB_DATA_SECRET_ID=
+ export GA_TEST_KEY_EVENT_ID=
+ export GA_TEST_ACCOUNT_ACCESS_BINDING_ID=
+ export GA_TEST_PROPERTY_ACCESS_BINDING_ID=
+ ```
+
+4. Execute tests from the `google-analytics-admin` or `google-analytics-data`
+ directory, using either `nox` or `pytest`. Using `nox` provides the
+ additional benefit of formatting all files, and also automatically creates a
+ virtual environment to test samples using different versions of Python.
+
+ * Using `nox`:
+
+ ```sh
+ nox
+ ```
+
+ * Using `pytest`:
+
+ ```sh
+ pytest
+ ```
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/README.md b/README.md
index 349092b..a832a39 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,15 @@
-# python-docs-samples
\ No newline at end of file
+# Google Analytics Python Samples
+
+Python samples for [Google Analytics APIs][ga].
+
+Check out the `README.md` in one of the following directories to get started:
+
+- Admin API: [README.md](google-analytics-admin/README.md)
+- Data API: [README.md](google-analytics-data/README.md)
+
+## Contributing
+
+Contributions welcome! See the [Contributing Guide](CONTRIBUTING.md).
+
+[ga]: https://developers.google.com/analytics
+
diff --git a/google-analytics-admin/README.md b/google-analytics-admin/README.md
new file mode 100644
index 0000000..7cd267c
--- /dev/null
+++ b/google-analytics-admin/README.md
@@ -0,0 +1,38 @@
+# Google Analytics Admin API examples
+
+[![Open in Cloud Shell][shell_img]][shell_link]
+
+[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png
+[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleanalytics/python-docs-samples&page=editor&open_in_editor=/google-analytics-admin/README.md
+
+These samples show how to use the
+[Google Analytics Admin API](https://developers.google.com/analytics/devguides/config/admin/v1) from Python.
+
+## Build and Run
+
+1. **Enable APIs** - [Enable the Analytics Admin API](https://console.cloud.google.com/flows/enableapi?apiid=analyticsadmin.googleapis.com)
+ and create a new project or select an existing project.
+2. **Download The Credentials** - Configure your project using [Application Default Credentials][adc].
+ Click "Go to credentials" after enabling the APIs. Click "Create Credentials"
+ and select "Service Account Credentials" and download the credentials file. Then set the path to
+ this file to the environment variable `GOOGLE_APPLICATION_CREDENTIALS`:
+ ```sh
+ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
+ ```
+3. **Clone the repo** and cd into this directory
+ ```sh
+ git clone https://github.com/googleanalytics/python-docs-samples
+ cd python-docs-samples/google-analytics-admin
+ ```
+4. **Install dependencies** via [pip3](https://pip.pypa.io/en/stable).
+ ```sh
+ pip3 install --upgrade -r requirements.txt
+ ```
+5. **Review the comments starting with `TODO(developer)` and update the code
+to use correct values.**
+6. **Run** with the command `python3 SNIPPET_NAME.py`. For example:
+ ```sh
+ python3 quickstart.py
+ ```
+
+[adc]: https://cloud.google.com/docs/authentication#adc
diff --git a/google-analytics-admin/account_summaries_list.py b/google-analytics-admin/account_summaries_list.py
new file mode 100644
index 0000000..9efd7ca
--- /dev/null
+++ b/google-analytics-admin/account_summaries_list.py
@@ -0,0 +1,56 @@
+#!/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(transport: str = None) -> None:
+ """
+ Prints summaries of all accounts accessible by the caller.
+
+ Args:
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ 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/google-analytics-admin/account_summaries_list_test.py b/google-analytics-admin/account_summaries_list_test.py
new file mode 100644
index 0000000..c132782
--- /dev/null
+++ b/google-analytics-admin/account_summaries_list_test.py
@@ -0,0 +1,23 @@
+# 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):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ account_summaries_list.list_account_summaries(transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_access_bindings_batch_create.py b/google-analytics-admin/accounts_access_bindings_batch_create.py
new file mode 100644
index 0000000..07f423b
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_create.py
@@ -0,0 +1,88 @@
+#!/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 creates a access binding for
+the account using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/batchCreate
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_batch_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ BatchCreateAccessBindingsRequest,
+ CreateAccessBindingRequest,
+)
+
+
+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"
+
+ # TODO(developer): Replace this variable with an email address of the user to
+ # link. This user will be given access to your account after running the
+ # sample.
+ email_address = "TEST-EMAIL-ADDRESS"
+
+ batch_create_account_access_binding(account_id, email_address)
+
+
+def batch_create_account_access_binding(
+ account_id: str, email_address: str, transport: str = None
+):
+ """
+ Creates a access binding for the account using a batch call.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ email_address(str): Email address of the access binding user.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ response = client.batch_create_access_bindings(
+ BatchCreateAccessBindingsRequest(
+ parent=f"accounts/{account_id}",
+ requests=[
+ CreateAccessBindingRequest(
+ access_binding=AccessBinding(
+ user=email_address,
+ roles=["predefinedRoles/read"],
+ )
+ )
+ ],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_accounts_access_bindings_batch_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_batch_create_test.py b/google-analytics-admin/accounts_access_bindings_batch_create_test.py
new file mode 100644
index 0000000..ad77f65
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_create_test.py
@@ -0,0 +1,31 @@
+# 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_access_bindings_batch_create
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_EMAIL_ADDRESS = "FAKE_EMAIL_ADDRESS"
+
+
+def test_accounts_access_bindings_batch_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_access_bindings_batch_create.batch_create_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_EMAIL_ADDRESS, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_access_bindings_batch_delete.py b/google-analytics-admin/accounts_access_bindings_batch_delete.py
new file mode 100644
index 0000000..7d54995
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_delete.py
@@ -0,0 +1,80 @@
+#!/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 the access binding
+using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/batchDelete
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_batch_delete]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ BatchDeleteAccessBindingsRequest,
+ DeleteAccessBindingRequest,
+)
+
+
+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 property 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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_delete_account_access_binding(account_id, account_access_binding_id)
+
+
+def batch_delete_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Deletes the access binding using a batch call.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.batch_delete_access_bindings(
+ BatchDeleteAccessBindingsRequest(
+ parent=f"accounts/{account_id}",
+ requests=[
+ DeleteAccessBindingRequest(
+ name=f"accounts/{account_id}/accessBindings/{account_access_binding_id}"
+ )
+ ],
+ )
+ )
+ print("Access binding deleted")
+
+
+# [END analyticsadmin_accounts_access_bindings_batch_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_batch_delete_test.py b/google-analytics-admin/accounts_access_bindings_batch_delete_test.py
new file mode 100644
index 0000000..1977bdf
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_delete_test.py
@@ -0,0 +1,31 @@
+# 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_access_bindings_batch_delete
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_ACCOUNT_ACCESS_BINDING_ID = "1"
+
+
+def test_accounts_access_bindings_batch_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_access_bindings_batch_delete.batch_delete_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_access_bindings_batch_get.py b/google-analytics-admin/accounts_access_bindings_batch_get.py
new file mode 100644
index 0000000..f5779c0
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_get.py
@@ -0,0 +1,71 @@
+#!/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 details for
+the account access binding using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/batchGet
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_batch_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import BatchGetAccessBindingsRequest
+
+
+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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_get_account_access_binding(account_id, account_access_binding_id)
+
+
+def batch_get_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Retrieves details for the account access binding using a batch call.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ response = client.batch_get_access_bindings(
+ BatchGetAccessBindingsRequest(
+ parent=f"accounts/{account_id}",
+ names=[f"accounts/{account_id}/accessBindings/{account_access_binding_id}"],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_accounts_access_bindings_batch_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_batch_get_test.py b/google-analytics-admin/accounts_access_bindings_batch_get_test.py
new file mode 100644
index 0000000..681f4c0
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_get_test.py
@@ -0,0 +1,30 @@
+# 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_access_bindings_batch_get
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+TEST_ACCOUNT_ACCESS_BINDING_ID = os.getenv("GA_TEST_ACCOUNT_ACCESS_BINDING_ID")
+
+
+def test_accounts_access_bindings_batch_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_access_bindings_batch_get.batch_get_account_access_binding(
+ TEST_ACCOUNT_ID, TEST_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_access_bindings_batch_update.py b/google-analytics-admin/accounts_access_bindings_batch_update.py
new file mode 100644
index 0000000..7095105
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_update.py
@@ -0,0 +1,90 @@
+#!/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 account
+access binding using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/batchUpdate
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_batch_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ BatchUpdateAccessBindingsRequest,
+ UpdateAccessBindingRequest,
+)
+
+
+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 property 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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_update_account_access_binding(account_id, account_access_binding_id)
+
+
+def batch_update_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Updates the account access binding using a batch call.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the roles of the access binding. The access binding to
+ # update is specified in the `name` field of the `AccessBinding` instance.
+ response = client.batch_update_access_bindings(
+ BatchUpdateAccessBindingsRequest(
+ parent=f"accounts/{account_id}",
+ requests=[
+ UpdateAccessBindingRequest(
+ access_binding=AccessBinding(
+ name=f"accounts/{account_id}/accessBindings/{account_access_binding_id}",
+ roles=["predefinedRoles/collaborate"],
+ ),
+ )
+ ],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_accounts_access_bindings_batch_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_batch_update_test.py b/google-analytics-admin/accounts_access_bindings_batch_update_test.py
new file mode 100644
index 0000000..722db41
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_batch_update_test.py
@@ -0,0 +1,31 @@
+# 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_access_bindings_batch_update
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_ACCOUNT_ACCESS_BINDING_ID = "1"
+
+
+def test_accounts_access_bindings_batch_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_access_bindings_batch_update.batch_update_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_access_bindings_create.py b/google-analytics-admin/accounts_access_bindings_create.py
new file mode 100644
index 0000000..bacd8c1
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_create.py
@@ -0,0 +1,80 @@
+#!/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 creates a access binding
+for the account.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/create
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ CreateAccessBindingRequest,
+)
+
+
+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"
+
+ # TODO(developer): Replace this variable with an email address of the user to
+ # link. This user will be given access to your account after running the
+ # sample.
+ email_address = "TEST-EMAIL-ADDRESS"
+
+ create_account_access_binding(account_id, email_address)
+
+
+def create_account_access_binding(
+ account_id: str, email_address: str, transport: str = None
+):
+ """
+ Creates a access binding for the account.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ email_address(str): Email address of the access binding user.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ access_binding = client.create_access_binding(
+ CreateAccessBindingRequest(
+ parent=f"accounts/{account_id}",
+ access_binding=AccessBinding(
+ user=email_address, roles=["predefinedRoles/read"]
+ ),
+ )
+ )
+
+ print("Result:")
+ print(access_binding)
+
+
+# [END analyticsadmin_accounts_access_bindings_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_create_test.py b/google-analytics-admin/accounts_access_bindings_create_test.py
new file mode 100644
index 0000000..93845cf
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_create_test.py
@@ -0,0 +1,31 @@
+# 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_access_bindings_create
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_EMAIL_ADDRESS = "FAKE_EMAIL_ADDRESS"
+
+
+def test_accounts_access_bindings_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_access_bindings_create.create_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_EMAIL_ADDRESS, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_access_bindings_delete.py b/google-analytics-admin/accounts_access_bindings_delete.py
new file mode 100644
index 0000000..146b6a4
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_delete.py
@@ -0,0 +1,72 @@
+#!/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 the access binding
+for the account.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/delete
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_delete]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import DeleteAccessBindingRequest
+
+
+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 property 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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ delete_account_access_binding(account_id, account_access_binding_id)
+
+
+def delete_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Deletes the access binding for the account.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_access_binding(
+ DeleteAccessBindingRequest(
+ name=f"accounts/{account_id}/accessBindings/{account_access_binding_id}"
+ )
+ )
+ print("Access binding deleted")
+
+
+# [END analyticsadmin_accounts_access_bindings_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_delete_test.py b/google-analytics-admin/accounts_access_bindings_delete_test.py
new file mode 100644
index 0000000..a7c98eb
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_delete_test.py
@@ -0,0 +1,31 @@
+# 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_access_bindings_delete
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_ACCOUNT_ACCESS_BINDING_ID = "1"
+
+
+def test_accounts_access_bindings_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_access_bindings_delete.delete_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_access_bindings_get.py b/google-analytics-admin/accounts_access_bindings_get.py
new file mode 100644
index 0000000..c6d3828
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_get.py
@@ -0,0 +1,73 @@
+#!/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 account user
+link details.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/get
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ get_account_access_binding(account_id, account_access_binding_id)
+
+
+def get_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Retrieves the account access binding details.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ access_binding = client.get_access_binding(
+ name=f"accounts/{account_id}/accessBindings/{account_access_binding_id}"
+ )
+
+ print("Result:")
+ print_access_binding(access_binding)
+
+
+def print_access_binding(access_binding):
+ """Prints the access binding details."""
+ print(f"Resource name: {access_binding.name}")
+ print(f"User: {access_binding.user}")
+ for role in access_binding.roles:
+ print(f"Role: {role}")
+
+
+# [END analyticsadmin_accounts_access_bindings_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_get_test.py b/google-analytics-admin/accounts_access_bindings_get_test.py
new file mode 100644
index 0000000..796e17b
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_get_test.py
@@ -0,0 +1,30 @@
+# 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_access_bindings_get
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+TEST_ACCOUNT_ACCESS_BINDING_ID = os.getenv("GA_TEST_ACCOUNT_ACCESS_BINDING_ID")
+
+
+def test_accounts_access_bindings_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_access_bindings_get.get_account_access_binding(
+ TEST_ACCOUNT_ID, TEST_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_access_bindings_list.py b/google-analytics-admin/accounts_access_bindings_list.py
new file mode 100644
index 0000000..ee8dae3
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_list.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 access bindings
+under the specified parent account.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/list
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_list]
+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"
+ list_account_access_bindings(account_id)
+
+
+def list_account_access_bindings(account_id: str, transport: str = None):
+ """
+ Lists access bindings under the specified parent account.
+
+ Args:
+ account_id(str): The id of the account.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_access_bindings(parent=f"accounts/{account_id}")
+
+ print("Result:")
+ for access_binding in results:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_accounts_access_bindings_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_list_test.py b/google-analytics-admin/accounts_access_bindings_list_test.py
new file mode 100644
index 0000000..1a3584d
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_list_test.py
@@ -0,0 +1,29 @@
+# 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_access_bindings_list
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+
+
+def test_accounts_access_bindings_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_access_bindings_list.list_account_access_bindings(
+ TEST_ACCOUNT_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_access_bindings_update.py b/google-analytics-admin/accounts_access_bindings_update.py
new file mode 100644
index 0000000..442cf4f
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_update.py
@@ -0,0 +1,77 @@
+#!/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 account
+access binding.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts.accessBindings/patch
+for more information.
+"""
+# [START analyticsadmin_accounts_access_bindings_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import AccessBinding
+
+
+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 property 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"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ account_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ update_account_access_binding(account_id, account_access_binding_id)
+
+
+def update_account_access_binding(
+ account_id: str, account_access_binding_id: str, transport: str = None
+):
+ """
+ Updates the account access binding.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ account_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the roles of the access binding. The access binding to
+ # update is specified in the `name` field of the `AccessBinding` instance.
+ access_binding = client.update_access_binding(
+ access_binding=AccessBinding(
+ name=f"accounts/{account_id}/accessBindings/{account_access_binding_id}",
+ roles=["predefinedRoles/collaborate"],
+ ),
+ )
+
+ print("Result:")
+ print(access_binding)
+
+
+# [END analyticsadmin_accounts_access_bindings_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_access_bindings_update_test.py b/google-analytics-admin/accounts_access_bindings_update_test.py
new file mode 100644
index 0000000..b6cb850
--- /dev/null
+++ b/google-analytics-admin/accounts_access_bindings_update_test.py
@@ -0,0 +1,34 @@
+# 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_access_bindings_update
+
+FAKE_ACCOUNT_ID = "1"
+FAKE_ACCOUNT_ACCESS_BINDING_ID = "1"
+
+
+def test_accounts_access_bindings_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="(The caller does not have permission|Invalid access binding name)",
+ ):
+ accounts_access_bindings_update.update_account_access_binding(
+ FAKE_ACCOUNT_ID, FAKE_ACCOUNT_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/accounts_delete.py b/google-analytics-admin/accounts_delete.py
new file mode 100644
index 0000000..44b6aba
--- /dev/null
+++ b/google-analytics-admin/accounts_delete.py
@@ -0,0 +1,59 @@
+#!/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, transport: str = None):
+ """
+ Deletes the Google Analytics account.
+
+ Args:
+ account_id(str): The id of the account to be deleted.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_account(name=f"accounts/{account_id}")
+ print("Account deleted")
+
+
+# [END analyticsadmin_accounts_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_delete_test.py b/google-analytics-admin/accounts_delete_test.py
new file mode 100644
index 0000000..76f8dd7
--- /dev/null
+++ b/google-analytics-admin/accounts_delete_test.py
@@ -0,0 +1,29 @@
+# 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():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_delete.delete_account(FAKE_ACCOUNT_ID, transport=transport)
diff --git a/google-analytics-admin/accounts_get.py b/google-analytics-admin/accounts_get.py
new file mode 100644
index 0000000..221cf18
--- /dev/null
+++ b/google-analytics-admin/accounts_get.py
@@ -0,0 +1,63 @@
+#!/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, transport: str = None):
+ """
+ Retrieves the Google Analytics account data.
+ Args:
+ account_id(str): The id of the account.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ 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/google-analytics-admin/accounts_get_data_sharing_settings.py b/google-analytics-admin/accounts_get_data_sharing_settings.py
new file mode 100644
index 0000000..be43a00
--- /dev/null
+++ b/google-analytics-admin/accounts_get_data_sharing_settings.py
@@ -0,0 +1,66 @@
+#!/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, transport=None):
+ """
+ Gets data sharing settings on an account.
+ Args:
+ account_id(str): The id of the account.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ 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/google-analytics-admin/accounts_get_data_sharing_settings_test.py b/google-analytics-admin/accounts_get_data_sharing_settings_test.py
new file mode 100644
index 0000000..2ac0cac
--- /dev/null
+++ b/google-analytics-admin/accounts_get_data_sharing_settings_test.py
@@ -0,0 +1,29 @@
+# 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):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_get_data_sharing_settings.get_data_sharing_settings(
+ TEST_ACCOUNT_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_get_test.py b/google-analytics-admin/accounts_get_test.py
new file mode 100644
index 0000000..c982c47
--- /dev/null
+++ b/google-analytics-admin/accounts_get_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 os
+
+import accounts_get
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+
+
+def test_accounts_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_get.get_account(TEST_ACCOUNT_ID, transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_list.py b/google-analytics-admin/accounts_list.py
new file mode 100644
index 0000000..87a2c5e
--- /dev/null
+++ b/google-analytics-admin/accounts_list.py
@@ -0,0 +1,49 @@
+#!/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(transport: str = None):
+ """
+ Lists the Google Analytics accounts available to the current user.
+
+ Args:
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ 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/google-analytics-admin/accounts_list_test.py b/google-analytics-admin/accounts_list_test.py
new file mode 100644
index 0000000..d8c2f0f
--- /dev/null
+++ b/google-analytics-admin/accounts_list_test.py
@@ -0,0 +1,23 @@
+# 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):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_list.list_accounts(transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_provision_account_ticket.py b/google-analytics-admin/accounts_provision_account_ticket.py
new file mode 100644
index 0000000..977c74c
--- /dev/null
+++ b/google-analytics-admin/accounts_provision_account_ticket.py
@@ -0,0 +1,97 @@
+#!/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, 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, transport: str = None):
+ """
+ Provisions the Google Analytics account creation ticket.
+
+ Args:
+ redirect_uri(str): Redirect URI where the user will be sent
+ after accepting Terms of Service. Must be configured in
+ Developers Console as a Redirect URI.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ 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/google-analytics-admin/accounts_provision_account_ticket_test.py b/google-analytics-admin/accounts_provision_account_ticket_test.py
new file mode 100644
index 0000000..ca1f069
--- /dev/null
+++ b/google-analytics-admin/accounts_provision_account_ticket_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 accounts_provision_account_ticket
+
+TEST_REDIRECT_URL = "https://www.google.com"
+
+
+def test_accounts_provision_account_ticket(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_provision_account_ticket.provision_account_ticket(
+ TEST_REDIRECT_URL, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_search_change_history_events.py b/google-analytics-admin/accounts_search_change_history_events.py
new file mode 100644
index 0000000..313980f
--- /dev/null
+++ b/google-analytics-admin/accounts_search_change_history_events.py
@@ -0,0 +1,129 @@
+#!/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 displays the change
+history for the Google Analytics account.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/accounts/searchChangeHistoryEvents
+for more information.
+"""
+# [START analyticsadmin_accounts_search_change_history_events]
+from datetime import datetime, timedelta
+
+from google.analytics.admin import (
+ AnalyticsAdminServiceClient,
+ SearchChangeHistoryEventsRequest,
+)
+from google.analytics.admin_v1alpha.types import ActionType, ActorType
+from google.protobuf.timestamp_pb2 import Timestamp
+
+
+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"
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ search_change_history_events(account_id, property_id)
+
+
+def search_change_history_events(
+ account_id: str, property_id: str, transport: str = None
+):
+ """
+ Lists the change history events for the Google Analytics 4 property
+ within the specified date range.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # Create a timestamp object and subtract 7 days from the current date/time.
+ earliest_change_time = Timestamp()
+ earliest_change_time.FromDatetime(datetime.now() - timedelta(days=7))
+
+ results = client.search_change_history_events(
+ SearchChangeHistoryEventsRequest(
+ account=f"accounts/{account_id}",
+ property=f"properties/{property_id}",
+ action=["CREATED", "UPDATED"],
+ earliest_change_time=earliest_change_time,
+ )
+ )
+
+ print("Result:")
+ for event in results:
+ print(f"Event ID: {event.id}")
+ print(f"Change time: {event.change_time}")
+ print(f"Actor type: {ActorType(event.actor_type).name}")
+ print(f"User actor e-mail: {event.user_actor_email}")
+ print(f"Changes filtered: {event.changes_filtered}")
+ for change in event.changes:
+ print(" Change details")
+ print(f" Resource name: {change.resource}")
+ print(f" Action: {ActionType(change.action).name}")
+ print(" Resource before change: ")
+ print_resource(change.resource_before_change)
+ print(" Resource after change: ")
+ print_resource(change.resource_after_change)
+ print()
+
+
+def print_resource(resource):
+ """Prints the change history resource."""
+ # Detect the type of the resource by checking value of a oneof field.
+ if resource.property:
+ print(" Property resource")
+ elif resource.account:
+ print(" Account resource")
+ elif resource.data_stream:
+ print(" DataStream resource")
+ elif resource.firebase_link:
+ print(" FirebaseLink resource")
+ elif resource.google_ads_link:
+ print(" GoogleAdsLink resource")
+ elif resource.google_signals_settings:
+ print(" GoogleSignalsSettings resource")
+ elif resource.display_video_360_advertiser_link:
+ print(" DisplayVideo360AdvertiserLink resource")
+ elif resource.display_video_360_advertiser_link_proposal:
+ print(" DisplayVideo360AdvertiserLinkProposal resource")
+ elif resource.conversion_event:
+ print(" ConversionEvent resource")
+ elif resource.measurement_protocol_secret:
+ print(" MeasurementProtocolSecret resource")
+ elif resource.custom_dimension:
+ print(" CustomDimension resource")
+ elif resource.custom_metric:
+ print(" CustomMetric resource")
+ elif resource.data_retention_settings:
+ print(" DataRetentionSettings resource")
+ else:
+ print(" Resource not set")
+ print(f" Resource value: {resource}")
+ print()
+
+
+# [END analyticsadmin_accounts_search_change_history_events]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/accounts_search_change_history_events_test.py b/google-analytics-admin/accounts_search_change_history_events_test.py
new file mode 100644
index 0000000..8bc148f
--- /dev/null
+++ b/google-analytics-admin/accounts_search_change_history_events_test.py
@@ -0,0 +1,30 @@
+# 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_search_change_history_events
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_accounts_search_change_history_events(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ accounts_search_change_history_events.search_change_history_events(
+ TEST_ACCOUNT_ID, TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/accounts_update.py b/google-analytics-admin/accounts_update.py
new file mode 100644
index 0000000..602ff63
--- /dev/null
+++ b/google-analytics-admin/accounts_update.py
@@ -0,0 +1,76 @@
+#!/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/patch
+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, transport: str = None):
+ """
+ Updates the Google Analytics account.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # 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/google-analytics-admin/accounts_update_test.py b/google-analytics-admin/accounts_update_test.py
new file mode 100644
index 0000000..9481acc
--- /dev/null
+++ b/google-analytics-admin/accounts_update_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_update
+
+FAKE_ACCOUNT_ID = "1"
+
+
+def test_accounts_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ accounts_update.update_account(FAKE_ACCOUNT_ID, transport=transport)
diff --git a/google-analytics-admin/noxfile.py b/google-analytics-admin/noxfile.py
new file mode 100644
index 0000000..1581f3c
--- /dev/null
+++ b/google-analytics-admin/noxfile.py
@@ -0,0 +1,302 @@
+# 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 annotations
+from __future__ import print_function
+
+from collections.abc import Callable
+import glob
+import os
+from pathlib import Path
+import sys
+
+import nox
+
+
+# WARNING - WARNING - WARNING - WARNING - WARNING
+# WARNING - WARNING - WARNING - WARNING - WARNING
+# BE CAREFUL WHEN EDITING THIS FILE!
+# 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", "3.7", "3.9", "3.10", "3.11"],
+ # 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',
+ # If you need to use a specific version of pip,
+ # change pip_version_override to the string representation
+ # of the version number, for example, "20.2.4"
+ "pip_version_override": None,
+ # 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
+
+
+# All versions used to tested samples.
+ALL_VERSIONS = ["2.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
+
+# 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))
+
+# Error if a python version is missing
+nox.options.error_on_missing_interpreters = True
+
+#
+# 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 ensure 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:
+# ANN101: missing type annotation for self in method
+# 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=ANN101,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:
+ # check for presence of tests
+ test_list = glob.glob("*_test.py") + glob.glob("test_*.py")
+ test_list.extend(glob.glob("tests"))
+
+ if len(test_list) == 0:
+ print("No tests found, skipping directory.")
+ return
+
+ if TEST_CONFIG["pip_version_override"]:
+ pip_version = TEST_CONFIG["pip_version_override"]
+ session.install(f"pip=={pip_version}")
+ else:
+ session.install("--upgrade", "pip")
+
+ """Runs py.test for a particular project."""
+ concurrent_args = []
+ if os.path.exists("requirements.txt"):
+ with open("requirements.txt") as rfile:
+ packages = rfile.read()
+ if os.path.exists("constraints.txt"):
+ session.install(
+ "-r",
+ "requirements.txt",
+ "-c",
+ "constraints.txt",
+ "--only-binary",
+ ":all",
+ )
+ elif "pyspark" in packages:
+ session.install("-r", "requirements.txt", "--use-pep517")
+ else:
+ session.install("-r", "requirements.txt", "--only-binary", ":all")
+
+ if os.path.exists("requirements-test.txt"):
+ with open("requirements-test.txt") as rtfile:
+ packages += rtfile.read()
+ if os.path.exists("constraints-test.txt"):
+ session.install(
+ "-r",
+ "requirements-test.txt",
+ "-c",
+ "constraints-test.txt",
+ "--only-binary",
+ ":all",
+ )
+ else:
+ session.install("-r", "requirements-test.txt", "--only-binary", ":all")
+
+ if INSTALL_LIBRARY_FROM_SOURCE:
+ session.install("-e", _get_repo_root())
+
+ if post_install:
+ post_install(session)
+
+ if "pytest-parallel" in packages:
+ concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"])
+ elif "pytest-xdist" in packages:
+ concurrent_args.extend(["-n", "auto"])
+
+ session.run(
+ "pytest",
+ *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args),
+ # 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() -> str | None:
+ """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/google-analytics-admin/noxfile_config.py b/google-analytics-admin/noxfile_config.py
new file mode 100644
index 0000000..3d809ef
--- /dev/null
+++ b/google-analytics-admin/noxfile_config.py
@@ -0,0 +1,39 @@
+# 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
+
+TEST_CONFIG_OVERRIDE = {
+ # You can opt out from the test for specific Python versions.
+ "ignored_versions": ["2.7", "3.8", "3.9"],
+ # 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": os.getenv("GA_TEST_PROPERTY_ID", "276206997"),
+ "GA_TEST_ACCOUNT_ID": os.getenv("GA_TEST_ACCOUNT_ID", "199820965"),
+ "GA_TEST_WEB_DATA_STREAM_ID": os.getenv(
+ "GA_TEST_WEB_DATA_STREAM_ID", "2828068992"
+ ),
+ "GA_TEST_WEB_DATA_SECRET_ID": os.getenv(
+ "GA_TEST_WEB_DATA_SECRET_ID", "2994983412"
+ ),
+ "GA_TEST_KEY_EVENT_ID": os.getenv("GA_TEST_KEY_EVENT_ID", "2719963095"),
+ },
+}
diff --git a/google-analytics-admin/properties_access_bindings_batch_create.py b/google-analytics-admin/properties_access_bindings_batch_create.py
new file mode 100644
index 0000000..3c4383b
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_create.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 creates a access binding for
+the Google Analytics 4 property using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/batchCreate
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_batch_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ BatchCreateAccessBindingsRequest,
+ CreateAccessBindingRequest,
+)
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with an email address of the user to
+ # link. This user will be given access to your account after running the
+ # sample.
+ email_address = "TEST-EMAIL-ADDRESS"
+
+ batch_create_property_access_binding(property_id, email_address)
+
+
+def batch_create_property_access_binding(
+ property_id: str, email_address: str, transport: str = None
+):
+ """
+ Creates a access binding for the Google Analytics 4 property using a batch
+ call.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ email_address(str): Email address of the access binding user.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ response = client.batch_create_access_bindings(
+ BatchCreateAccessBindingsRequest(
+ parent=f"properties/{property_id}",
+ requests=[
+ CreateAccessBindingRequest(
+ access_binding=AccessBinding(
+ user=email_address,
+ roles=["predefinedRoles/read"],
+ )
+ )
+ ],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_properties_access_bindings_batch_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_batch_create_test.py b/google-analytics-admin/properties_access_bindings_batch_create_test.py
new file mode 100644
index 0000000..0984e2b
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_create_test.py
@@ -0,0 +1,31 @@
+# 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 properties_access_bindings_batch_create
+
+FAKE_PROPERTY_ID = "1"
+FAKE_EMAIL_ADDRESS = "test@google.com"
+
+
+def test_properties_access_bindings_batch_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_access_bindings_batch_create.batch_create_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_EMAIL_ADDRESS, transport=transport
+ )
diff --git a/google-analytics-admin/properties_access_bindings_batch_delete.py b/google-analytics-admin/properties_access_bindings_batch_delete.py
new file mode 100644
index 0000000..522d7a3
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_delete.py
@@ -0,0 +1,80 @@
+#!/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 delete the access binding for
+the Google Analytics 4 property using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/batchDelete
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_batch_delete]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ BatchDeleteAccessBindingsRequest,
+ DeleteAccessBindingRequest,
+)
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_delete_property_access_binding(property_id, property_access_binding_id)
+
+
+def batch_delete_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Deletes the GA4 property access binding using a batch call.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.batch_delete_access_bindings(
+ BatchDeleteAccessBindingsRequest(
+ parent=f"properties/{property_id}",
+ requests=[
+ DeleteAccessBindingRequest(
+ name=f"properties/{property_id}/accessBindings/{property_access_binding_id}"
+ )
+ ],
+ )
+ )
+ print("Access binding deleted")
+
+
+# [END analyticsadmin_properties_access_bindings_batch_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_batch_delete_test.py b/google-analytics-admin/properties_access_bindings_batch_delete_test.py
new file mode 100644
index 0000000..a88a2c0
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_access_bindings_batch_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_ACCESS_BINDING_ID = "1"
+
+
+def test_properties_access_bindings_batch_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_access_bindings_batch_delete.batch_delete_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_access_bindings_batch_get.py b/google-analytics-admin/properties_access_bindings_batch_get.py
new file mode 100644
index 0000000..b377fa9
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_get.py
@@ -0,0 +1,74 @@
+#!/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 details for the
+Google Analytics 4 property access binding using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/batchGet
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_batch_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import BatchGetAccessBindingsRequest
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_get_property_access_binding(property_id, property_access_binding_id)
+
+
+def batch_get_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Retrieves details for the Google Analytics 4 property access binding using a
+ batch call.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ response = client.batch_get_access_bindings(
+ BatchGetAccessBindingsRequest(
+ parent=f"properties/{property_id}",
+ names=[
+ f"properties/{property_id}/accessBindings/{property_access_binding_id}"
+ ],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_properties_access_bindings_batch_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_batch_get_test.py b/google-analytics-admin/properties_access_bindings_batch_get_test.py
new file mode 100644
index 0000000..fd7f443
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_get_test.py
@@ -0,0 +1,30 @@
+# 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 properties_access_bindings_batch_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_ACCESS_BINDING_ID = os.getenv("GA_TEST_PROPERTY_ACCESS_BINDING_ID")
+
+
+def test_properties_access_bindings_batch_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_access_bindings_batch_get.batch_get_property_access_binding(
+ TEST_PROPERTY_ID, TEST_ACCESS_BINDING_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_access_bindings_batch_update.py b/google-analytics-admin/properties_access_bindings_batch_update.py
new file mode 100644
index 0000000..01cbfde
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_update.py
@@ -0,0 +1,90 @@
+#!/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 4 property access binding using a batch call.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/batchUpdate
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_batch_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ BatchUpdateAccessBindingsRequest,
+ UpdateAccessBindingRequest,
+)
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ batch_update_property_access_binding(property_id, property_access_binding_id)
+
+
+def batch_update_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Updates the Google Analytics 4 property access binding using a batch call.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the roles of the access binding. The access binding to
+ # update is specified in the `name` field of the `AccessBinding` instance.
+ response = client.batch_update_access_bindings(
+ BatchUpdateAccessBindingsRequest(
+ parent=f"properties/{property_id}",
+ requests=[
+ UpdateAccessBindingRequest(
+ access_binding=AccessBinding(
+ name=f"properties/{property_id}/accessBindings/{property_access_binding_id}",
+ roles=["predefinedRoles/collaborate"],
+ ),
+ )
+ ],
+ )
+ )
+
+ print("Result:")
+ for access_binding in response.access_bindings:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_properties_access_bindings_batch_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_batch_update_test.py b/google-analytics-admin/properties_access_bindings_batch_update_test.py
new file mode 100644
index 0000000..a9ff413
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_batch_update_test.py
@@ -0,0 +1,31 @@
+# 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 properties_access_bindings_batch_update
+
+FAKE_PROPERTY_ID = "1"
+FAKE_ACCESS_BINDING_ID = "1"
+
+
+def test_properties_access_bindings_batch_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_access_bindings_batch_update.batch_update_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_access_bindings_create.py b/google-analytics-admin/properties_access_bindings_create.py
new file mode 100644
index 0000000..3b42ebf
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_create.py
@@ -0,0 +1,80 @@
+#!/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 creates a access binding for
+the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/create
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessBinding,
+ CreateAccessBindingRequest,
+)
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with an email address of the user to
+ # link. This user will be given access to your account after running the
+ # sample.
+ email_address = "TEST-EMAIL-ADDRESS"
+
+ create_property_access_binding(property_id, email_address)
+
+
+def create_property_access_binding(
+ property_id: str, email_address: str, transport: str = None
+):
+ """
+ Creates a access binding for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ email_address(str): Email address of the access binding user.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ access_binding = client.create_access_binding(
+ CreateAccessBindingRequest(
+ parent=f"properties/{property_id}",
+ access_binding=AccessBinding(
+ user=email_address, roles=["predefinedRoles/read"]
+ ),
+ )
+ )
+
+ print("Result:")
+ print(access_binding)
+
+
+# [END analyticsadmin_properties_access_bindings_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_create_test.py b/google-analytics-admin/properties_access_bindings_create_test.py
new file mode 100644
index 0000000..35df694
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_create_test.py
@@ -0,0 +1,31 @@
+# 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 properties_access_bindings_create
+
+FAKE_PROPERTY_ID = "1"
+FAKE_EMAIL_ADDRESS = "test@google.com"
+
+
+def test_properties_access_bindings_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_access_bindings_create.create_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_EMAIL_ADDRESS, transport=transport
+ )
diff --git a/google-analytics-admin/properties_access_bindings_delete.py b/google-analytics-admin/properties_access_bindings_delete.py
new file mode 100644
index 0000000..3c63589
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_delete.py
@@ -0,0 +1,72 @@
+#!/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 the access binding
+from the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/delete
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_delete]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import DeleteAccessBindingRequest
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ delete_property_access_binding(property_id, property_access_binding_id)
+
+
+def delete_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Deletes the access binding from the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_access_binding(
+ DeleteAccessBindingRequest(
+ name=f"properties/{property_id}/accessBindings/{property_access_binding_id}"
+ )
+ )
+ print("Access binding deleted")
+
+
+# [END analyticsadmin_properties_access_bindings_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_delete_test.py b/google-analytics-admin/properties_access_bindings_delete_test.py
new file mode 100644
index 0000000..17bfbb6
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_access_bindings_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_ACCESS_BINDING_ID = "1"
+
+
+def test_properties_access_bindings_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_access_bindings_delete.delete_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_access_bindings_get.py b/google-analytics-admin/properties_access_bindings_get.py
new file mode 100644
index 0000000..14a1b40
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_get.py
@@ -0,0 +1,73 @@
+#!/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 4 property access binding details.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/get
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ get_property_access_binding(property_id, property_access_binding_id)
+
+
+def get_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Retrieves the Google Analytics 4 property access binding details.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ access_binding = client.get_access_binding(
+ name=f"properties/{property_id}/accessBindings/{property_access_binding_id}"
+ )
+
+ print("Result:")
+ print_access_binding(access_binding)
+
+
+def print_access_binding(access_binding):
+ """Prints the access binding details."""
+ print(f"Resource name: {access_binding.name}")
+ print(f"User: {access_binding.user}")
+ for role in access_binding.roles:
+ print(f"Role: {role}")
+
+
+# [END analyticsadmin_properties_access_bindings_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_get_test.py b/google-analytics-admin/properties_access_bindings_get_test.py
new file mode 100644
index 0000000..21015f8
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_get_test.py
@@ -0,0 +1,30 @@
+# 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 properties_access_bindings_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_ACCESS_BINDING_ID = os.getenv("GA_TEST_PROPERTY_ACCESS_BINDING_ID")
+
+
+def test_properties_access_bindings_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_access_bindings_get.get_property_access_binding(
+ TEST_PROPERTY_ID, TEST_ACCESS_BINDING_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_access_bindings_list.py b/google-analytics-admin/properties_access_bindings_list.py
new file mode 100644
index 0000000..38ee944
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_list.py
@@ -0,0 +1,58 @@
+#!/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 access bindings under
+the specified parent Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/list
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ list_property_access_bindings(property_id)
+
+
+def list_property_access_bindings(property_id: str, transport: str = None):
+ """
+ Lists access bindings under the specified parent Google Analytics 4
+ property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_access_bindings(parent=f"properties/{property_id}")
+
+ print("Result:")
+ for access_binding in results:
+ print(access_binding)
+ print()
+
+
+# [END analyticsadmin_properties_access_bindings_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_list_test.py b/google-analytics-admin/properties_access_bindings_list_test.py
new file mode 100644
index 0000000..4b0b251
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_list_test.py
@@ -0,0 +1,29 @@
+# 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 properties_access_bindings_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_access_bindings_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_access_bindings_list.list_property_access_bindings(
+ TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_access_bindings_update.py b/google-analytics-admin/properties_access_bindings_update.py
new file mode 100644
index 0000000..9ec08f9
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_update.py
@@ -0,0 +1,77 @@
+#!/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 4 property access binding.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.accessBindings/update
+for more information.
+"""
+# [START analyticsadmin_properties_access_bindings_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import AccessBinding
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics
+ # account access binding ID (e.g. "123456") before running the sample.
+ property_access_binding_id = "YOUR-ACCOUNT-ACCESS-BINDING-ID"
+
+ update_property_access_binding(property_id, property_access_binding_id)
+
+
+def update_property_access_binding(
+ property_id: str, property_access_binding_id: str, transport: str = None
+):
+ """
+ Updates the Google Analytics 4 property access binding.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ property_access_binding_id(str): Google Analytics account access binding ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the roles of the access binding. The access binding to
+ # update is specified in the `name` field of the `AccessBinding` instance.
+ access_binding = client.update_access_binding(
+ access_binding=AccessBinding(
+ name=f"properties/{property_id}/accessBindings/{property_access_binding_id}",
+ roles=["predefinedRoles/collaborate"],
+ ),
+ )
+
+ print("Result:")
+ print(access_binding)
+
+
+# [END analyticsadmin_properties_access_bindings_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_access_bindings_update_test.py b/google-analytics-admin/properties_access_bindings_update_test.py
new file mode 100644
index 0000000..c81af5d
--- /dev/null
+++ b/google-analytics-admin/properties_access_bindings_update_test.py
@@ -0,0 +1,34 @@
+# 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 properties_access_bindings_update
+
+FAKE_PROPERTY_ID = "1"
+FAKE_ACCESS_BINDING_ID = "1"
+
+
+def test_properties_access_bindings_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission|Invalid access binding name",
+ ):
+ properties_access_bindings_update.update_property_access_binding(
+ FAKE_PROPERTY_ID, FAKE_ACCESS_BINDING_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_create.py b/google-analytics-admin/properties_create.py
new file mode 100644
index 0000000..4b5cf8b
--- /dev/null
+++ b/google-analytics-admin/properties_create.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 creates a Google
+Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/create
+for more information.
+"""
+# [START analyticsadmin_properties_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import Property
+
+
+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"
+ create_property(account_id)
+
+
+def create_property(account_id: str, transport: str = None):
+ """
+ Creates a Google Analytics 4 property.
+
+ Args:
+ account_id(str): The Google Analytics Account ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ property_ = client.create_property(
+ property=Property(
+ parent=f"accounts/{account_id}",
+ currency_code="USD",
+ display_name="Test property",
+ industry_category="OTHER",
+ time_zone="America/Los_Angeles",
+ )
+ )
+
+ print("Result:")
+ print(property_)
+
+
+# [END analyticsadmin_properties_create]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_create_test.py b/google-analytics-admin/properties_create_test.py
new file mode 100644
index 0000000..e935ad3
--- /dev/null
+++ b/google-analytics-admin/properties_create_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 properties_create
+
+FAKE_ACCOUNT_ID = "1"
+
+
+def test_properties_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_create.create_property(FAKE_ACCOUNT_ID, transport=transport)
diff --git a/google-analytics-admin/properties_data_streams_create.py b/google-analytics-admin/properties_data_streams_create.py
new file mode 100644
index 0000000..a819447
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_create.py
@@ -0,0 +1,70 @@
+#!/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 creates a data stream
+for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams/create
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import DataStream
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ create_data_stream(property_id)
+
+
+def create_data_stream(property_id: str, transport: str = None):
+ """
+ Creates a data stream for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ data_stream = DataStream(
+ display_name="Test web data stream",
+ web_stream_data=DataStream.WebStreamData(default_uri="https://www.google.com"),
+ )
+ data_stream.type_ = "WEB_DATA_STREAM"
+ result = client.create_data_stream(
+ parent=f"properties/{property_id}",
+ data_stream=data_stream,
+ )
+
+ print("Result:")
+ print(result)
+
+
+# [END analyticsadmin_properties_data_streams_create]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_create_test.py b/google-analytics-admin/properties_data_streams_create_test.py
new file mode 100644
index 0000000..b6f7d69
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_create_test.py
@@ -0,0 +1,30 @@
+# 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 properties_data_streams_create
+
+FAKE_PROPERTY_ID = "1"
+
+
+def test_properties_data_streams_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_create.create_data_stream(
+ FAKE_PROPERTY_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_data_streams_delete.py b/google-analytics-admin/properties_data_streams_delete.py
new file mode 100644
index 0000000..7fe37fa
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_delete.py
@@ -0,0 +1,65 @@
+#!/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 the data
+stream from the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams/delete
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ delete_data_stream(property_id, stream_id)
+
+
+def delete_data_stream(property_id: str, stream_id: str, transport: str = None):
+ """
+ Deletes the data stream from the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_data_stream(name=f"properties/{property_id}/dataStreams/{stream_id}")
+ print("Data stream deleted")
+
+
+# [END analyticsadmin_properties_data_streams_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_delete_test.py b/google-analytics-admin/properties_data_streams_delete_test.py
new file mode 100644
index 0000000..75ec1a8
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_data_streams_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_STREAM_ID = "1"
+
+
+def test_properties_data_streams_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_delete.delete_data_stream(
+ FAKE_PROPERTY_ID, FAKE_STREAM_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_data_streams_get.py b/google-analytics-admin/properties_data_streams_get.py
new file mode 100644
index 0000000..789fb19
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_get.py
@@ -0,0 +1,75 @@
+#!/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 details for
+the data stream.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams/get
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ get_data_stream(property_id, stream_id)
+
+
+def get_data_stream(property_id: str, stream_id: str, transport: str = None):
+ """
+ Retrieves the details for the data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ data_stream = client.get_data_stream(
+ name=f"properties/{property_id}/dataStreams/{stream_id}"
+ )
+
+ print("Result:")
+ print_data_stream(data_stream)
+
+
+def print_data_stream(data_stream):
+ """Prints the data stream details."""
+ print(f"Resource name: {data_stream.name}")
+ print(f"Display name: {data_stream.display_name}")
+ print(f"Type: {data_stream.type}")
+ print(f"Default URI: {data_stream.web_stream_data.default_uri}")
+ print(f"Measurement ID: {data_stream.web_stream_data.measurement_id}")
+ print(f"Firebase App ID: {data_stream.web_stream_data.firebase_app_id}")
+ print(f"Create time: {data_stream.create_time}")
+ print(f"Update time: {data_stream.update_time}")
+
+
+# [END analyticsadmin_properties_data_streams_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_get_global_site_tag.py b/google-analytics-admin/properties_data_streams_get_global_site_tag.py
new file mode 100644
index 0000000..9bffcaa
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_get_global_site_tag.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 Site Tag data
+for the specified web stream.
+"""
+# [START analyticsadmin_properties_data_streams_get_global_site_tag]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ get_global_site_tag(property_id, stream_id)
+
+
+def get_global_site_tag(property_id: str, stream_id: str, transport: str = None):
+ """
+ Retrieves the Site Tag for the specified data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ global_site_tag = client.get_global_site_tag(
+ name=f"properties/{property_id}/dataStreams/{stream_id}/globalSiteTag"
+ )
+
+ print("Result:")
+ print(global_site_tag.snippet)
+
+
+# [END analyticsadmin_properties_data_streams_get_global_site_tag]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_get_global_site_tag_test.py b/google-analytics-admin/properties_data_streams_get_global_site_tag_test.py
new file mode 100644
index 0000000..05d4b36
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_get_global_site_tag_test.py
@@ -0,0 +1,30 @@
+# 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 properties_data_streams_get_global_site_tag
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_DATA_STREAM_ID = os.getenv("GA_TEST_WEB_DATA_STREAM_ID")
+
+
+def test_properties_data_streams_get_global_site_tag(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_data_streams_get_global_site_tag.get_global_site_tag(
+ TEST_PROPERTY_ID, TEST_DATA_STREAM_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_data_streams_get_test.py b/google-analytics-admin/properties_data_streams_get_test.py
new file mode 100644
index 0000000..c56e696
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_get_test.py
@@ -0,0 +1,30 @@
+# 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 properties_data_streams_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_DATA_STREAM_ID = os.getenv("GA_TEST_WEB_DATA_STREAM_ID")
+
+
+def test_properties_data_streams_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_data_streams_get.get_data_stream(
+ TEST_PROPERTY_ID, TEST_DATA_STREAM_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_data_streams_list.py b/google-analytics-admin/properties_data_streams_list.py
new file mode 100644
index 0000000..18c64ff
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_list.py
@@ -0,0 +1,58 @@
+#!/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 data streams
+for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams/list
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ list_data_streams(property_id)
+
+
+def list_data_streams(property_id: str, transport: str = None):
+ """
+ Lists data streams for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_data_streams(parent=f"properties/{property_id}")
+
+ print("Result:")
+ for data_stream in results:
+ print(data_stream)
+ print()
+
+
+# [END analyticsadmin_properties_data_streams_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_list_test.py b/google-analytics-admin/properties_data_streams_list_test.py
new file mode 100644
index 0000000..b988595
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_list_test.py
@@ -0,0 +1,29 @@
+# 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 properties_data_streams_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_data_streams_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_data_streams_list.list_data_streams(
+ TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create.py
new file mode 100644
index 0000000..a7926d7
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 creates a measurement
+protocol secret for the data stream.
+
+"""
+# [START analyticsadmin_properties_data_streams_measurement_protocol_secrets_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha import MeasurementProtocolSecret
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ create_measurement_protocol_secret(property_id, stream_id)
+
+
+def create_measurement_protocol_secret(
+ property_id: str, stream_id: str, transport: str = None
+):
+ """
+ Creates a measurement protocol secret for the data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ measurement_protocol_secret = client.create_measurement_protocol_secret(
+ parent=f"properties/{property_id}/dataStreams/{stream_id}",
+ measurement_protocol_secret=MeasurementProtocolSecret(
+ display_name="New secret"
+ ),
+ )
+
+ print("Result:")
+ print(f"Resource name: {measurement_protocol_secret.name}")
+ print(f"Secret value: {measurement_protocol_secret.secret_value}")
+ print(f"Display name: {measurement_protocol_secret.display_name}")
+
+
+# [END analyticsadmin_properties_data_streams_measurement_protocol_secrets_create]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create_test.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create_test.py
new file mode 100644
index 0000000..298d0dc
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_create_test.py
@@ -0,0 +1,31 @@
+# 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 properties_data_streams_measurement_protocol_secrets_create
+
+FAKE_PROPERTY_ID = "1"
+FAKE_STREAM_ID = "1"
+
+
+def test_properties_data_streams_measurement_protocol_secrets_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_measurement_protocol_secrets_create.create_measurement_protocol_secret(
+ FAKE_PROPERTY_ID, FAKE_STREAM_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete.py
new file mode 100644
index 0000000..81b1918
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete.py
@@ -0,0 +1,72 @@
+#!/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 measurement
+protocol secret for the data stream.
+
+"""
+# [START analyticsadmin_properties_data_streams_measurement_protocol_secrets_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ # TODO(developer): Replace this variable with your measurement protocol
+ # secret ID (e.g. "123456") before running the sample.
+ secret_id = "YOUR-MEASUREMENT-PROTOCOL-SECRET-ID"
+
+ delete_measurement_protocol_secret(property_id, stream_id, secret_id)
+
+
+def delete_measurement_protocol_secret(
+ property_id: str, stream_id: str, secret_id: str, transport: str = None
+):
+ """
+ Deletes a measurement protocol secret for the data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ secret_id(str): The measurement protocol secret ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_measurement_protocol_secret(
+ name=f"properties/{property_id}/dataStreams/{stream_id}/measurementProtocolSecrets/{secret_id}"
+ )
+ print("Measurement protocol secret deleted")
+
+
+# [END analyticsadmin_properties_data_streams_measurement_protocol_secrets_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete_test.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete_test.py
new file mode 100644
index 0000000..d892c89
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_delete_test.py
@@ -0,0 +1,32 @@
+# 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 properties_data_streams_measurement_protocol_secrets_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_STREAM_ID = "1"
+FAKE_SECRET_ID = "1"
+
+
+def test_properties_data_streams_measurement_protocol_secrets_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_measurement_protocol_secrets_delete.delete_measurement_protocol_secret(
+ FAKE_PROPERTY_ID, FAKE_STREAM_ID, FAKE_SECRET_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get.py
new file mode 100644
index 0000000..15720f8
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 retrieves the details
+for the measurement protocol secret.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams.measurementProtocolSecrets/get
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_measurement_protocol_secrets_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ # TODO(developer): Replace this variable with your measurement protocol
+ # secret ID (e.g. "123456") before running the sample.
+ secret_id = "YOUR-MEASUREMENT-PROTOCOL-SECRET-ID"
+
+ get_measurement_protocol_secret(property_id, stream_id, secret_id)
+
+
+def get_measurement_protocol_secret(
+ property_id: str, stream_id: str, secret_id: str, transport: str = None
+):
+ """
+ Retrieves the details for the measurement protocol secret.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ secret_id(str): The measurement protocol secret ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ measurement_protocol_secret = client.get_measurement_protocol_secret(
+ name=f"properties/{property_id}/dataStreams/{stream_id}/measurementProtocolSecrets/{secret_id}"
+ )
+
+ print("Result:")
+ print(f"Resource name: {measurement_protocol_secret.name}")
+ print(f"Secret value: {measurement_protocol_secret.secret_value}")
+ print(f"Display name: {measurement_protocol_secret.display_name}")
+
+
+# [END analyticsadmin_properties_data_streams_measurement_protocol_secrets_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get_test.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get_test.py
new file mode 100644
index 0000000..1e55aba
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_get_test.py
@@ -0,0 +1,31 @@
+# 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 properties_data_streams_measurement_protocol_secrets_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_STREAM_ID = os.getenv("GA_TEST_WEB_DATA_STREAM_ID")
+TEST_SECRET_ID = os.getenv("GA_TEST_WEB_DATA_SECRET_ID")
+
+
+def test_properties_data_streams_measurement_protocol_secrets_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_data_streams_measurement_protocol_secrets_get.get_measurement_protocol_secret(
+ TEST_PROPERTY_ID, TEST_STREAM_ID, TEST_SECRET_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list.py
new file mode 100644
index 0000000..beeea20
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 lists measurement
+protocol secrets for the data stream.
+
+"""
+# [START analyticsadmin_properties_data_streams_measurement_protocol_secrets_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+ list_measurement_protocol_secrets(property_id, stream_id)
+
+
+def list_measurement_protocol_secrets(
+ property_id: str, stream_id: str, transport: str = None
+):
+ """
+ Lists measurement protocol secrets for the data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_measurement_protocol_secrets(
+ parent=f"properties/{property_id}/dataStreams/{stream_id}"
+ )
+
+ print("Result:")
+ for measurement_protocol_secret in results:
+ print("Result:")
+ print(f"Resource name: {measurement_protocol_secret.name}")
+ print(f"Secret value: {measurement_protocol_secret.secret_value}")
+ print(f"Display name: {measurement_protocol_secret.display_name}")
+ print()
+
+
+# [END analyticsadmin_properties_data_streams_measurement_protocol_secrets_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list_test.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list_test.py
new file mode 100644
index 0000000..7b0238f
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_list_test.py
@@ -0,0 +1,30 @@
+# 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 properties_data_streams_measurement_protocol_secrets_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_DATA_STREAM_ID = os.getenv("GA_TEST_WEB_DATA_STREAM_ID")
+
+
+def test_properties_data_streams_measurement_protocol_secrets_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_data_streams_measurement_protocol_secrets_list.list_measurement_protocol_secrets(
+ TEST_PROPERTY_ID, TEST_DATA_STREAM_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update.py
new file mode 100644
index 0000000..b37335d
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 measurement
+protocol secret for the data stream.
+
+"""
+# [START analyticsadmin_properties_data_streams_measurement_protocol_secrets_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha import MeasurementProtocolSecret
+from google.protobuf.field_mask_pb2 import FieldMask
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ # TODO(developer): Replace this variable with your measurement protocol
+ # secret ID (e.g. "123456") before running the sample.
+ secret_id = "YOUR-MEASUREMENT-PROTOCOL-SECRET-ID"
+
+ update_measurement_protocol_secret(property_id, stream_id, secret_id)
+
+
+def update_measurement_protocol_secret(
+ property_id: str, stream_id: str, secret_id: str, transport: str = None
+):
+ """
+ Updates the measurement protocol secret.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ secret_id(str): The measurement protocol secret ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the display name of the measurement protocol secret, as
+ # indicated by the value of the `update_mask` field. The measurement
+ # protocol secret to update is specified in the `name` field of the
+ # `MeasurementProtocolSecret` instance.
+ measurement_protocol_secret = client.update_measurement_protocol_secret(
+ measurement_protocol_secret=MeasurementProtocolSecret(
+ name=f"properties/{property_id}/dataStreams/{stream_id}/measurementProtocolSecrets/{secret_id}",
+ display_name="This is an updated measurement protocol secret",
+ ),
+ update_mask=FieldMask(paths=["display_name"]),
+ )
+
+ print("Result:")
+ print(f"Resource name: {measurement_protocol_secret.name}")
+ print(f"Secret value: {measurement_protocol_secret.secret_value}")
+ print(f"Display name: {measurement_protocol_secret.display_name}")
+
+
+# [END analyticsadmin_properties_data_streams_measurement_protocol_secrets_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update_test.py b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update_test.py
new file mode 100644
index 0000000..5a6455c
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_measurement_protocol_secrets_update_test.py
@@ -0,0 +1,32 @@
+# 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 properties_data_streams_measurement_protocol_secrets_update
+
+FAKE_PROPERTY_ID = "1"
+FAKE_STREAM_ID = "1"
+FAKE_SECRET_ID = "1"
+
+
+def test_properties_data_streams_measurement_protocol_secrets_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_measurement_protocol_secrets_update.update_measurement_protocol_secret(
+ FAKE_PROPERTY_ID, FAKE_STREAM_ID, FAKE_SECRET_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_data_streams_update.py b/google-analytics-admin/properties_data_streams_update.py
new file mode 100644
index 0000000..e3de375
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_update.py
@@ -0,0 +1,78 @@
+#!/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 data
+stream.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.dataStreams/update
+for more information.
+"""
+# [START analyticsadmin_properties_data_streams_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import DataStream
+from google.protobuf.field_mask_pb2 import FieldMask
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your data stream ID
+ # (e.g. "123456") before running the sample.
+ stream_id = "YOUR-DATA-STREAM-ID"
+
+ update_data_stream(property_id, stream_id)
+
+
+def update_data_stream(property_id: str, stream_id: str, transport: str = None):
+ """
+ Updates the data stream.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ stream_id(str): The data stream ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the display name of the data stream, as indicated by
+ # the value of the `update_mask` field. The data stream to update is
+ # specified in the `name` field of the `dataStream` instance.
+ data_stream = client.update_data_stream(
+ data_stream=DataStream(
+ name=f"properties/{property_id}/dataStreams/{stream_id}",
+ display_name="This is an updated test data stream",
+ ),
+ update_mask=FieldMask(paths=["display_name"]),
+ )
+
+ print("Result:")
+ print(data_stream)
+
+
+# [END analyticsadmin_properties_data_streams_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_data_streams_update_test.py b/google-analytics-admin/properties_data_streams_update_test.py
new file mode 100644
index 0000000..0cae934
--- /dev/null
+++ b/google-analytics-admin/properties_data_streams_update_test.py
@@ -0,0 +1,31 @@
+# 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 properties_data_streams_update
+
+FAKE_PROPERTY_ID = "1"
+FAKE_STREAM_ID = "1"
+
+
+def test_properties_data_streams_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_data_streams_update.update_data_stream(
+ FAKE_PROPERTY_ID, FAKE_STREAM_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_delete.py b/google-analytics-admin/properties_delete.py
new file mode 100644
index 0000000..2e05f3c
--- /dev/null
+++ b/google-analytics-admin/properties_delete.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 the Google
+Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/delete
+for more information.
+"""
+# [START analyticsadmin_properties_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ delete_property(property_id)
+
+
+def delete_property(property_id: str, transport: str = None):
+ """
+ Deletes the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_property(name=f"properties/{property_id}")
+ print("Property deleted")
+
+
+# [END analyticsadmin_properties_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_delete_test.py b/google-analytics-admin/properties_delete_test.py
new file mode 100644
index 0000000..7b929ea
--- /dev/null
+++ b/google-analytics-admin/properties_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 properties_delete
+
+FAKE_PROPERTY_ID = "1"
+
+
+def test_properties_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_delete.delete_property(FAKE_PROPERTY_ID, transport=transport)
diff --git a/google-analytics-admin/properties_firebase_links_create.py b/google-analytics-admin/properties_firebase_links_create.py
new file mode 100644
index 0000000..34ea83a
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_create.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 creates a Firebase link
+for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.firebaseLinks/create
+for more information.
+"""
+# [START analyticsadmin_properties_firebase_links_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import FirebaseLink
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with a Firebase project id.
+ # This project will be linked to the GA4 property.
+ firebase_project_id = "YOUR-FIREBASE-PROJECT-ID"
+
+ create_firebase_link(property_id, firebase_project_id)
+
+
+def create_firebase_link(
+ property_id: str, firebase_project_id: str, transport: str = None
+):
+ """
+ Creates a Firebase link for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ firebase_project_id: Firebase project ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ firebase_link = client.create_firebase_link(
+ parent=f"properties/{property_id}",
+ firebase_link=FirebaseLink(project=f"projects/{firebase_project_id}"),
+ )
+
+ print("Result:")
+ print(firebase_link)
+
+
+# [END analyticsadmin_properties_firebase_links_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_firebase_links_create_test.py b/google-analytics-admin/properties_firebase_links_create_test.py
new file mode 100644
index 0000000..d19702a
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_create_test.py
@@ -0,0 +1,31 @@
+# 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 properties_firebase_links_create
+
+FAKE_PROPERTY_ID = "1"
+FAKE_FIREBASE_PROJECT_ID = "1"
+
+
+def test_properties_firebase_links_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_firebase_links_create.create_firebase_link(
+ FAKE_PROPERTY_ID, FAKE_FIREBASE_PROJECT_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_firebase_links_delete.py b/google-analytics-admin/properties_firebase_links_delete.py
new file mode 100644
index 0000000..a6a76f7
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_delete.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 the Firebase
+link from the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.firebaseLinks/delete
+for more information.
+"""
+# [START analyticsadmin_properties_firebase_links_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Firebase link ID
+ # (e.g. "123456") before running the sample.
+ firebase_link_id = "YOUR-FIREBASE-LINK-ID"
+
+ delete_firebase_link(property_id, firebase_link_id)
+
+
+def delete_firebase_link(
+ property_id: str, firebase_link_id: str, transport: str = None
+):
+ """
+ Deletes the Firebase link.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ firebase_link_id: The Firebase link ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_firebase_link(
+ name=f"properties/{property_id}/firebaseLinks/{firebase_link_id}"
+ )
+ print("Firebase link deleted")
+
+
+# [END analyticsadmin_properties_firebase_links_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_firebase_links_delete_test.py b/google-analytics-admin/properties_firebase_links_delete_test.py
new file mode 100644
index 0000000..c8b1db3
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_firebase_links_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_FIREBASE_LINK_ID = "1"
+
+
+def test_properties_firebase_links_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_firebase_links_delete.delete_firebase_link(
+ FAKE_PROPERTY_ID, FAKE_FIREBASE_LINK_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_firebase_links_list.py b/google-analytics-admin/properties_firebase_links_list.py
new file mode 100644
index 0000000..6c27b75
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_list.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Firebase links
+under the specified parent Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.firebaseLinks/list
+for more information.
+"""
+# [START analyticsadmin_properties_firebase_links_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ list_firebase_links(property_id)
+
+
+def list_firebase_links(property_id: str, transport: str = None):
+ """
+ Lists Firebase links under the specified parent Google Analytics 4
+ property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_firebase_links(parent=f"properties/{property_id}")
+
+ print("Result:")
+ for firebase_link in results:
+ print_firebase_link(firebase_link)
+ print()
+
+
+def print_firebase_link(firebase_link):
+ """Prints the Firebase link details."""
+ print(f"Resource name: {firebase_link.name}")
+ print(f"Firebase project: {firebase_link.project}")
+ print(f"Create time: {firebase_link.create_time}")
+
+
+# [END analyticsadmin_properties_firebase_links_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_firebase_links_list_test.py b/google-analytics-admin/properties_firebase_links_list_test.py
new file mode 100644
index 0000000..936bd62
--- /dev/null
+++ b/google-analytics-admin/properties_firebase_links_list_test.py
@@ -0,0 +1,29 @@
+# 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 properties_firebase_links_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_firebase_links_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_firebase_links_list.list_firebase_links(
+ TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_get.py b/google-analytics-admin/properties_get.py
new file mode 100644
index 0000000..ccbee42
--- /dev/null
+++ b/google-analytics-admin/properties_get.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 print the Google
+Analytics 4 property details.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/get
+for more information.
+"""
+# [START analyticsadmin_properties_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import IndustryCategory
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ get_property(property_id)
+
+
+def get_property(property_id: str, transport: str = None):
+ """
+ Retrieves the Google Analytics 4 property details.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ property_ = client.get_property(name=f"properties/{property_id}")
+
+ print("Result:")
+ print_property(property_)
+
+
+def print_property(property):
+ """Prints the Google Analytics 4 property details."""
+ print(f"Resource name: {property.name}")
+ print(f"Parent: {property.parent}")
+ print(f"Display name: {property.display_name}")
+ print(f"Create time: {property.create_time}")
+ print(f"Update time: {property.update_time}")
+ # print(f"Delete time: {property.delete_time}")
+ # print(f"Expire time: {property.expire_time}")
+
+ if property.industry_category:
+ print(f"Industry category: {IndustryCategory(property.industry_category).name}")
+
+ print(f"Time zone: {property.time_zone}")
+ print(f"Currency code: {property.currency_code}")
+
+
+# [END analyticsadmin_properties_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_get_test.py b/google-analytics-admin/properties_get_test.py
new file mode 100644
index 0000000..a770c39
--- /dev/null
+++ b/google-analytics-admin/properties_get_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 os
+
+import properties_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_get.get_property(TEST_PROPERTY_ID, transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_google_ads_links_create.py b/google-analytics-admin/properties_google_ads_links_create.py
new file mode 100644
index 0000000..9abf575
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_create.py
@@ -0,0 +1,73 @@
+#!/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 creates a Google Ads
+link for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.googleAdsLinks/create
+for more information.
+"""
+# [START analyticsadmin_properties_google_ads_links_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import GoogleAdsLink
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with a ten-digit Google Ads
+ # customer ID (digits only, e.g. "1234567890").
+ # This Google Ads account will be linked to the GA4 property.
+ google_ads_customer_id = "YOUR-GOOGLE-ADS-CUSTOMER-ID"
+
+ create_google_ads_link(property_id, google_ads_customer_id)
+
+
+def create_google_ads_link(
+ property_id: str, google_ads_customer_id: str, transport: str = None
+):
+ """
+ Creates a Google Ads link for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ google_ads_customer_id(str): The Google Analytics Ads Customer Id.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ google_ads_link = client.create_google_ads_link(
+ parent=f"properties/{property_id}",
+ google_ads_link=GoogleAdsLink(customer_id=f"{google_ads_customer_id}"),
+ )
+
+ print("Result:")
+ print(google_ads_link)
+
+
+# [END analyticsadmin_properties_google_ads_links_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_google_ads_links_create_test.py b/google-analytics-admin/properties_google_ads_links_create_test.py
new file mode 100644
index 0000000..1e19e5c
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_create_test.py
@@ -0,0 +1,31 @@
+# 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 properties_google_ads_links_create
+
+FAKE_PROPERTY_ID = "1"
+FAKE_ADS_CUSTOMER_ID = "1234567890"
+
+
+def test_properties_google_ads_links_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_google_ads_links_create.create_google_ads_link(
+ FAKE_PROPERTY_ID, FAKE_ADS_CUSTOMER_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_google_ads_links_delete.py b/google-analytics-admin/properties_google_ads_links_delete.py
new file mode 100644
index 0000000..b3451c1
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_delete.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 deletes the Google Ads link
+from the specified Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.googleAdsLinks/delete
+for more information.
+"""
+# [START analyticsadmin_properties_google_ads_links_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics Ads
+ # link ID (e.g. "123456") before running the sample.
+ google_ads_link_id = "YOUR-GOOGLE-ADS-LINK-ID"
+
+ delete_google_ads_link(property_id, google_ads_link_id)
+
+
+def delete_google_ads_link(
+ property_id: str, google_ads_link_id: str, transport: str = None
+):
+ """
+ Deletes the Google Ads link.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ google_ads_link_id(str): The Google Analytics Ads Link Id.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_google_ads_link(
+ name=f"properties/{property_id}/googleAdsLinks/{google_ads_link_id}"
+ )
+ print("Google Ads link deleted")
+
+
+# [END analyticsadmin_properties_google_ads_links_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_google_ads_links_delete_test.py b/google-analytics-admin/properties_google_ads_links_delete_test.py
new file mode 100644
index 0000000..527e29b
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_google_ads_links_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_GOOGLE_ADS_LINK_ID = "1"
+
+
+def test_properties_google_ads_links_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_google_ads_links_delete.delete_google_ads_link(
+ FAKE_PROPERTY_ID, FAKE_GOOGLE_ADS_LINK_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_google_ads_links_list.py b/google-analytics-admin/properties_google_ads_links_list.py
new file mode 100644
index 0000000..c23f041
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_list.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 prints Google Ads links
+under the specified parent Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.googleAdsLinks/list
+for more information.
+"""
+# [START analyticsadmin_properties_google_ads_links_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ list_google_ads_links(property_id)
+
+
+def list_google_ads_links(property_id: str, transport: str = None):
+ """
+ Lists Google Ads links under the specified parent Google Analytics 4
+ property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_google_ads_links(parent=f"properties/{property_id}")
+
+ print("Result:")
+ for google_ads_link in results:
+ print_google_ads_link(google_ads_link)
+ print()
+
+
+def print_google_ads_link(google_ads_link):
+ """Prints the Google Ads link details."""
+ print(f"Resource name: {google_ads_link.name}")
+ print(f"Google Ads customer ID: {google_ads_link.customer_id}")
+ print(f"Can manage clients: {google_ads_link.can_manage_clients}")
+ print(f"Ads personalization enabled: {google_ads_link.ads_personalization_enabled}")
+ print(f"Email address of the link creator: {google_ads_link.creator_email_address}")
+ print(f"Create time: {google_ads_link.create_time}")
+ print(f"Update time: {google_ads_link.update_time}")
+
+
+# [END analyticsadmin_properties_google_ads_links_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_google_ads_links_list_test.py b/google-analytics-admin/properties_google_ads_links_list_test.py
new file mode 100644
index 0000000..e8252b9
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_list_test.py
@@ -0,0 +1,29 @@
+# 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 properties_google_ads_links_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_google_ads_links_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_google_ads_links_list.list_google_ads_links(
+ TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_google_ads_links_update.py b/google-analytics-admin/properties_google_ads_links_update.py
new file mode 100644
index 0000000..b5e1395
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_update.py
@@ -0,0 +1,80 @@
+#!/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 updates the Google Ads link.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.googleAdsLinks/update
+for more information.
+"""
+# [START analyticsadmin_properties_google_ads_links_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import GoogleAdsLink
+from google.protobuf.field_mask_pb2 import FieldMask
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your Google Analytics Ads
+ # link ID (e.g. "123456") before running the sample.
+ google_ads_link_id = "YOUR-GOOGLE-ADS-LINK-ID"
+
+ update_google_ads_link(property_id, google_ads_link_id)
+
+
+def update_google_ads_link(
+ property_id: str, google_ads_link_id: str, transport: str = None
+):
+ """
+ Updates the Google Ads link.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ google_ads_link_id(str): The Google Analytics Ads Link Id.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the adsPersonalizationEnabled setting of the
+ # Google Ads link as indicated by the value of the `update_mask` field.
+ # The Google Ads link to update is specified in the `name` field of the
+ # `Google AdsLink` instance.
+ google_ads_link = client.update_google_ads_link(
+ google_ads_link=GoogleAdsLink(
+ name=f"properties/{property_id}/googleAdsLinks/{google_ads_link_id}",
+ ads_personalization_enabled=False,
+ ),
+ update_mask=FieldMask(paths=["ads_personalization_enabled"]),
+ )
+
+ print("Result:")
+ print(google_ads_link)
+
+
+# [END analyticsadmin_properties_google_ads_links_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_google_ads_links_update_test.py b/google-analytics-admin/properties_google_ads_links_update_test.py
new file mode 100644
index 0000000..1cc4b2d
--- /dev/null
+++ b/google-analytics-admin/properties_google_ads_links_update_test.py
@@ -0,0 +1,31 @@
+# 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 properties_google_ads_links_update
+
+FAKE_PROPERTY_ID = "1"
+FAKE_GOOGLE_ADS_LINK_ID = "1"
+
+
+def test_properties_google_ads_links_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_google_ads_links_update.update_google_ads_link(
+ FAKE_PROPERTY_ID, FAKE_GOOGLE_ADS_LINK_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_key_events_create.py b/google-analytics-admin/properties_key_events_create.py
new file mode 100644
index 0000000..11fcdab
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_create.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 creates a key
+event for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.keyEvents/create
+for more information.
+"""
+# [START analyticsadmin_properties_key_events_create]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha import KeyEvent
+
+
+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 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ create_key_event(property_id)
+
+
+def create_key_event(property_id: str, transport: str = None):
+ """
+ Creates a key event for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ key_event = client.create_key_event(
+ parent=f"properties/{property_id}",
+ key_event=KeyEvent(event_name="test_purchase"),
+ )
+
+ print("Result:")
+ print(f"Resource name: {key_event.name}")
+ print(f"Event name: {key_event.event_name}")
+ print(f"Create time: {key_event.create_time}")
+ print(f"Deletable: {key_event.deletable}")
+ print(f"Custom: {key_event.custom}")
+
+
+# [END analyticsadmin_properties_key_events_create]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_key_events_create_test.py b/google-analytics-admin/properties_key_events_create_test.py
new file mode 100644
index 0000000..85aa23c
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_create_test.py
@@ -0,0 +1,30 @@
+# 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 properties_key_events_create
+
+FAKE_PROPERTY_ID = "1"
+
+
+def test_properties_key_events_create():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_key_events_create.create_key_event(
+ FAKE_PROPERTY_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_key_events_delete.py b/google-analytics-admin/properties_key_events_delete.py
new file mode 100644
index 0000000..047db74
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_delete.py
@@ -0,0 +1,66 @@
+#!/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 key
+event for the Google Analytics 4 property.
+
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.keyEvents/delete
+for more information.
+"""
+# [START analyticsadmin_properties_key_events_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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your key event ID
+ # (e.g. "123456") before running the sample.
+ key_event_id = "YOUR-KEY-EVENT-ID"
+
+ delete_key_event(property_id, key_event_id)
+
+
+def delete_key_event(property_id: str, key_event_id: str, transport: str = None):
+ """
+ Deletes the key event for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ key_event_id(str): The key event ID
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ client.delete_key_event(name=f"properties/{property_id}/keyEvents/{key_event_id}")
+ print("Key event deleted")
+
+
+# [END analyticsadmin_properties_key_events_delete]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_key_events_delete_test.py b/google-analytics-admin/properties_key_events_delete_test.py
new file mode 100644
index 0000000..678ecf4
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_delete_test.py
@@ -0,0 +1,31 @@
+# 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 properties_key_events_delete
+
+FAKE_PROPERTY_ID = "1"
+FAKE_KEY_EVENT_ID = "1"
+
+
+def test_properties_key_events_delete():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_key_events_delete.delete_key_event(
+ FAKE_PROPERTY_ID, FAKE_KEY_EVENT_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_key_events_get.py b/google-analytics-admin/properties_key_events_get.py
new file mode 100644
index 0000000..e888018
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_get.py
@@ -0,0 +1,66 @@
+#!/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 key
+event details.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.keyEvents/get
+for more information.
+"""
+# [START analyticsadmin_properties_key_events_get]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # TODO(developer): Replace this variable with your key event ID
+ # (e.g. "123456") before running the sample.
+ key_event_id = "YOUR-KEY-EVENT-ID"
+
+ get_key_event(property_id, key_event_id)
+
+
+def get_key_event(property_id: str, key_event_id: str, transport: str = None):
+ """
+ Retrieves the details for the key event.
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ key_event_id(str): The key event ID
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ key_event = client.get_key_event(
+ name=f"properties/{property_id}/keyEvents/{key_event_id}"
+ )
+
+ print("Result:")
+ print(f"Resource name: {key_event.name}")
+ print(f"Event name: {key_event.event_name}")
+ print(f"Create time: {key_event.create_time}")
+ print(f"Deletable: {key_event.deletable}")
+ print(f"Custom: {key_event.custom}")
+
+
+# [END analyticsadmin_properties_key_events_get]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_key_events_get_test.py b/google-analytics-admin/properties_key_events_get_test.py
new file mode 100644
index 0000000..076a09b
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_get_test.py
@@ -0,0 +1,30 @@
+# 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 properties_key_events_get
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+TEST_KEY_EVENT_ID = os.getenv("GA_TEST_KEY_EVENT_ID")
+
+
+def test_properties_key_events_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_key_events_get.get_key_event(
+ TEST_PROPERTY_ID, TEST_KEY_EVENT_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_key_events_list.py b/google-analytics-admin/properties_key_events_list.py
new file mode 100644
index 0000000..e67824d
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_list.py
@@ -0,0 +1,62 @@
+#!/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 lists key events
+for the Google Analytics 4 property.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties.keyEvents/list
+for more information.
+"""
+# [START analyticsadmin_properties_key_events_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+
+ list_key_events(property_id)
+
+
+def list_key_events(property_id: str, transport: str = None):
+ """
+ Lists key events for the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_key_events(parent=f"properties/{property_id}")
+
+ print("Result:")
+ for key_event in results:
+ print(f"Resource name: {key_event.name}")
+ print(f"Event name: {key_event.event_name}")
+ print(f"Create time: {key_event.create_time}")
+ print(f"Deletable: {key_event.deletable}")
+ print(f"Custom: {key_event.custom}")
+ print()
+
+
+# [END analyticsadmin_properties_key_events_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_key_events_list_test.py b/google-analytics-admin/properties_key_events_list_test.py
new file mode 100644
index 0000000..3acbe3f
--- /dev/null
+++ b/google-analytics-admin/properties_key_events_list_test.py
@@ -0,0 +1,29 @@
+# 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 properties_key_events_list
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_key_events_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_key_events_list.list_key_events(
+ TEST_PROPERTY_ID, transport=transport
+ )
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_list.py b/google-analytics-admin/properties_list.py
new file mode 100644
index 0000000..e467fbc
--- /dev/null
+++ b/google-analytics-admin/properties_list.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Google Analytics 4
+properties under the specified parent account that are available to the
+current user.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/list
+for more information.
+"""
+# [START analyticsadmin_properties_list]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import ListPropertiesRequest
+
+
+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"
+ list_properties(account_id)
+
+
+def list_properties(account_id: str, transport: str = None):
+ """
+ Lists Google Analytics 4 properties under the specified parent account
+ that are available to the current user.
+
+ Args:
+ account_id(str): The Google Analytics account ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ results = client.list_properties(
+ ListPropertiesRequest(filter=f"parent:accounts/{account_id}", show_deleted=True)
+ )
+
+ print("Result:")
+ for property_ in results:
+ print(property_)
+ print()
+
+
+# [END analyticsadmin_properties_list]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_list_test.py b/google-analytics-admin/properties_list_test.py
new file mode 100644
index 0000000..e9f4667
--- /dev/null
+++ b/google-analytics-admin/properties_list_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 os
+
+import properties_list
+
+TEST_ACCOUNT_ID = os.getenv("GA_TEST_ACCOUNT_ID")
+
+
+def test_properties_get(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ properties_list.list_properties(TEST_ACCOUNT_ID, transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/properties_run_access_report.py b/google-analytics-admin/properties_run_access_report.py
new file mode 100644
index 0000000..6e51909
--- /dev/null
+++ b/google-analytics-admin/properties_run_access_report.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+# Copyright 2022 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 runs an access report
+on a property.
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/runAccessReport
+for more information.
+"""
+# [START analyticsadmin_properties_run_access_report]
+from datetime import datetime
+
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import (
+ AccessDateRange,
+ AccessDimension,
+ AccessMetric,
+ RunAccessReportRequest,
+)
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_access_report(property_id)
+
+
+def run_access_report(property_id: str, transport: str = None):
+ """
+ Runs an access report for a Google Analytics property. The report will
+ aggregate over dimensions `userEmail`, `accessedPropertyId`,
+ `reportType`, `revenueDataReturned`, `costDataReturned`,
+ `userIP`, and return the access count, as well as the most recent access
+ time for each combination.
+ See https://developers.google.com/analytics/devguides/config/admin/v1/access-api-schema
+ for the description of each field used in a data access report query.
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ request = RunAccessReportRequest(
+ entity=f"properties/{property_id}",
+ dimensions=[
+ AccessDimension(dimension_name="userEmail"),
+ AccessDimension(dimension_name="accessedPropertyId"),
+ AccessDimension(dimension_name="reportType"),
+ AccessDimension(dimension_name="revenueDataReturned"),
+ AccessDimension(dimension_name="costDataReturned"),
+ AccessDimension(dimension_name="userIP"),
+ AccessDimension(dimension_name="mostRecentAccessEpochTimeMicros"),
+ ],
+ metrics=[AccessMetric(metric_name="accessCount")],
+ date_ranges=[AccessDateRange(start_date="yesterday", end_date="today")],
+ )
+
+ access_report = client.run_access_report(request)
+
+ print("Result:")
+ print_access_report(access_report)
+
+
+def print_access_report(response):
+ """Prints the access report."""
+ print(f"{response.row_count} rows received")
+ for dimensionHeader in response.dimension_headers:
+ print(f"Dimension header name: {dimensionHeader.dimension_name}")
+ for metricHeader in response.metric_headers:
+ print(f"Metric header name: {metricHeader.metric_name})")
+
+ for rowIdx, row in enumerate(response.rows):
+ print(f"\nRow {rowIdx}")
+ for i, dimension_value in enumerate(row.dimension_values):
+ dimension_name = response.dimension_headers[i].dimension_name
+ if dimension_name.endswith("Micros"):
+ # Convert microseconds since Unix Epoch to datetime object.
+ dimension_value_formatted = datetime.utcfromtimestamp(
+ int(dimension_value.value) / 1000000
+ )
+ else:
+ dimension_value_formatted = dimension_value.value
+ print(f"{dimension_name}: {dimension_value_formatted}")
+
+ for i, metric_value in enumerate(row.metric_values):
+ metric_name = response.metric_headers[i].metric_name
+ print(f"{metric_name}: {metric_value.value}")
+
+
+# [END analyticsadmin_properties_run_access_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_run_access_report_test.py b/google-analytics-admin/properties_run_access_report_test.py
new file mode 100644
index 0000000..764072c
--- /dev/null
+++ b/google-analytics-admin/properties_run_access_report_test.py
@@ -0,0 +1,36 @@
+# Copyright 2022 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 pytest
+
+import properties_run_access_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_properties_run_access_report(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # This test ensures that the call is valid and reaches the server, even
+ # though the operation does not succeed due to the test property not
+ # being a Google Analytics 360 property.
+ with pytest.raises(
+ Exception,
+ match="Data Access Reports are only allowed on Google Analytics 360 properties.",
+ ):
+ properties_run_access_report.run_access_report(
+ TEST_PROPERTY_ID, transport=transport
+ )
diff --git a/google-analytics-admin/properties_update.py b/google-analytics-admin/properties_update.py
new file mode 100644
index 0000000..e6c3264
--- /dev/null
+++ b/google-analytics-admin/properties_update.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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.
+
+See https://developers.google.com/analytics/devguides/config/admin/v1/rest/v1alpha/properties/update
+for more information.
+"""
+# [START analyticsadmin_properties_update]
+from google.analytics.admin import AnalyticsAdminServiceClient
+from google.analytics.admin_v1alpha.types import Property
+from google.protobuf.field_mask_pb2 import FieldMask
+
+
+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 property ID from
+ # your production environment below.
+
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID (e.g. "123456") before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ update_property(property_id)
+
+
+def update_property(property_id: str, transport: str = None):
+ """
+ Updates the Google Analytics 4 property.
+
+ Args:
+ property_id(str): The Google Analytics Property ID.
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ client = AnalyticsAdminServiceClient(transport=transport)
+ # This call updates the display name, industry category and time zone of the
+ # property, as indicated by the value of the `update_mask` field.
+ # The property to update is specified in the `name` field of the `Property`
+ # instance.
+ property_ = client.update_property(
+ property=Property(
+ name=f"properties/{property_id}",
+ display_name="This is an updated test property",
+ industry_category="GAMES",
+ time_zone="America/New_York",
+ ),
+ update_mask=FieldMask(paths=["display_name", "time_zone", "industry_category"]),
+ )
+
+ print("Result:")
+ print(property_)
+
+
+# [END analyticsadmin_properties_update]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-admin/properties_update_test.py b/google-analytics-admin/properties_update_test.py
new file mode 100644
index 0000000..b55e5d4
--- /dev/null
+++ b/google-analytics-admin/properties_update_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 properties_update
+
+FAKE_PROPERTY_ID = "1"
+
+
+def test_properties_update():
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ # 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="The caller does not have permission"):
+ properties_update.update_property(FAKE_PROPERTY_ID, transport=transport)
diff --git a/google-analytics-admin/quickstart.py b/google-analytics-admin/quickstart.py
new file mode 100644
index 0000000..8cdca97
--- /dev/null
+++ b/google-analytics-admin/quickstart.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+
+# Copyright 2020 Google Inc. 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 quickstart application.
+Example usage:
+ python quickstart.py
+
+This application demonstrates the usage of the Analytics Admin API using
+service account credentials. For more information on service accounts, see
+
+https://cloud.google.com/iam/docs/understanding-service-accounts
+
+The following document provides instructions on setting service account
+credentials for your application:
+
+ https://cloud.google.com/docs/authentication/production
+
+In a nutshell, you need to:
+1. Create a service account and download the key JSON file.
+
+https://cloud.google.com/docs/authentication/production#creating_a_service_account
+
+2. Provide service account credentials using one of the following options:
+- set the GOOGLE_APPLICATION_CREDENTIALS environment variable, the API
+client will use the value of this variable to find the service account key
+JSON file.
+
+https://cloud.google.com/docs/authentication/production#setting_the_environment_variable
+
+OR
+- manually pass the path to the service account key JSON file to the API client
+by specifying the keyFilename parameter in the constructor:
+https://cloud.google.com/docs/authentication/production#passing_the_path_to_the_service_account_key_in_code
+
+To install the latest published package dependency, execute the following:
+ pip install google-analytics-admin
+"""
+
+
+# [START ga_admin_list_accounts]
+def list_accounts(transport: str = None):
+ """
+ Lists the available Google Analytics accounts.
+
+ Args:
+ transport(str): The transport to use. For example, "grpc"
+ or "rest". If set to None, a transport is chosen automatically.
+ """
+ from google.analytics.admin import AnalyticsAdminServiceClient
+
+ # Using a default constructor instructs the client to use the credentials
+ # specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
+ client = AnalyticsAdminServiceClient(transport=transport)
+
+ results = client.list_accounts()
+
+ # Displays the configuration information for all Google Analytics accounts
+ # available to the authenticated user.
+ print("Result:")
+ for account in results:
+ print(account)
+
+
+# [END ga_admin_list_accounts]
+
+
+if __name__ == "__main__":
+ list_accounts()
diff --git a/google-analytics-admin/quickstart_test.py b/google-analytics-admin/quickstart_test.py
new file mode 100644
index 0000000..0b703c2
--- /dev/null
+++ b/google-analytics-admin/quickstart_test.py
@@ -0,0 +1,23 @@
+# Copyright 2022 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 quickstart
+
+
+def test_accounts_list(capsys):
+ transports = ["grpc", "rest"]
+ for transport in transports:
+ quickstart.list_accounts(transport=transport)
+ out, _ = capsys.readouterr()
+ assert "Result" in out
diff --git a/google-analytics-admin/requirements-test.txt b/google-analytics-admin/requirements-test.txt
new file mode 100644
index 0000000..31439ea
--- /dev/null
+++ b/google-analytics-admin/requirements-test.txt
@@ -0,0 +1 @@
+pytest==9.2.0
\ No newline at end of file
diff --git a/google-analytics-admin/requirements.txt b/google-analytics-admin/requirements.txt
new file mode 100644
index 0000000..69f29c0
--- /dev/null
+++ b/google-analytics-admin/requirements.txt
@@ -0,0 +1,2 @@
+google-analytics-admin==0.30.2
+google-auth-oauthlib==1.5.0
diff --git a/google-analytics-data/README.md b/google-analytics-data/README.md
new file mode 100644
index 0000000..b61aec0
--- /dev/null
+++ b/google-analytics-data/README.md
@@ -0,0 +1,39 @@
+# Google Analytics Data API examples
+
+[![Open in Cloud Shell][shell_img]][shell_link]
+
+[shell_img]: http://gstatic.com/cloudssh/images/open-btn.png
+[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleanalytics/python-docs-samples&page=editor&open_in_editor=/google-analytics-data/README.md
+
+These samples show how to use the
+[Google Analytics Data API](https://developers.google.com/analytics/devguides/reporting/data/v1) from Python.
+
+## Build and Run
+
+1. **Enable APIs** - [Enable the Analytics Data API](https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com)
+ and create a new project or select an existing project.
+2. **Download The Credentials** - Configure your project using [Application Default Credentials][adc].
+ Click "Go to credentials" after enabling the APIs. Click "Create Credentials"
+ and select "Service Account Credentials" and download the credentials file. Then set the path to
+ this file to the environment variable `GOOGLE_APPLICATION_CREDENTIALS`:
+
+ ```sh
+ export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
+ ```
+3. **Clone the repo** and cd into this directory
+ ```sh
+ git clone https://github.com/googleanalytics/python-docs-samples
+ cd python-docs-samples/google-analytics-data
+ ```
+4. **Install dependencies** via [pip3](https://pip.pypa.io/en/stable).
+ ```sh
+ pip3 install --upgrade -r requirements.txt
+ ```
+5. **Review the comments starting with `TODO(developer)` and update the code to
+ use correct values.**
+6. **Run** with the command `python3 SNIPPET_NAME.py`. For example:
+ ```sh
+ $ python3 quickstart.py
+ ```
+
+[adc]: https://cloud.google.com/docs/authentication#adc
diff --git a/google-analytics-data/get_common_metadata.py b/google-analytics-data/get_common_metadata.py
new file mode 100644
index 0000000..643cf55
--- /dev/null
+++ b/google-analytics-data/get_common_metadata.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application retrieving dimension and metrics
+metadata.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/getMetadata
+for more information.
+"""
+# [START analyticsdata_get_common_metadata]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import GetMetadataRequest, MetricType
+
+
+def run_sample():
+ """Runs the sample."""
+ get_common_metadata()
+
+
+def get_common_metadata():
+ """Retrieves dimensions and metrics available for all Google Analytics 4
+ properties."""
+ client = BetaAnalyticsDataClient()
+
+ # Set the Property ID to 0 for dimensions and metrics common
+ # to all properties. In this special mode, this method will
+ # not return custom dimensions and metrics.
+ property_id = 0
+ request = GetMetadataRequest(name=f"properties/{property_id}/metadata")
+ response = client.get_metadata(request)
+
+ print("Dimensions and metrics available for all Google Analytics 4 properties:")
+ print_get_metadata_response(response)
+
+
+def print_get_metadata_response(response):
+ """Prints results of the getMetadata call."""
+ # [START analyticsdata_print_get_metadata_response]
+ for dimension in response.dimensions:
+ print("DIMENSION")
+ print(f"{dimension.api_name} ({dimension.ui_name}): {dimension.description}")
+ print(f"custom_definition: {dimension.custom_definition}")
+ if dimension.deprecated_api_names:
+ print(f"Deprecated API names: {dimension.deprecated_api_names}")
+ print("")
+
+ for metric in response.metrics:
+ print("METRIC")
+ print(f"{metric.api_name} ({metric.ui_name}): {metric.description}")
+ print(f"custom_definition: {metric.custom_definition}")
+ if metric.expression:
+ print(f"Expression: {metric.expression}")
+
+ metric_type = MetricType(metric.type_).name
+ print(f"Type: {metric_type}")
+
+ if metric.deprecated_api_names:
+ print(f"Deprecated API names: {metric.deprecated_api_names}")
+ print("")
+ # [END analyticsdata_print_get_metadata_response]
+
+
+# [END analyticsdata_get_common_metadata]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/get_common_metadata_test.py b/google-analytics-data/get_common_metadata_test.py
new file mode 100644
index 0000000..ae11969
--- /dev/null
+++ b/google-analytics-data/get_common_metadata_test.py
@@ -0,0 +1,21 @@
+# Copyright 2021 Google Inc. 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 get_common_metadata
+
+
+def test_get_common_metadata(capsys):
+ get_common_metadata.get_common_metadata()
+ out, _ = capsys.readouterr()
+ assert "Dimensions and metrics" in out
diff --git a/google-analytics-data/get_metadata_by_property_id.py b/google-analytics-data/get_metadata_by_property_id.py
new file mode 100644
index 0000000..6950ced
--- /dev/null
+++ b/google-analytics-data/get_metadata_by_property_id.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application retrieving dimension and metrics
+metadata.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/getMetadata
+for more information.
+"""
+# [START analyticsdata_get_metadata_by_property_id]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import GetMetadataRequest
+
+from get_common_metadata import print_get_metadata_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ get_metadata_by_property_id(property_id)
+
+
+def get_metadata_by_property_id(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Retrieves dimensions and metrics available for a Google Analytics 4
+ property, including custom fields."""
+ client = BetaAnalyticsDataClient()
+
+ request = GetMetadataRequest(name=f"properties/{property_id}/metadata")
+ response = client.get_metadata(request)
+
+ print(
+ f"Dimensions and metrics available for Google Analytics 4 "
+ f"property {property_id} (including custom fields):"
+ )
+ print_get_metadata_response(response)
+
+
+# [END analyticsdata_get_metadata_by_property_id]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/get_metadata_by_property_id_test.py b/google-analytics-data/get_metadata_by_property_id_test.py
new file mode 100644
index 0000000..958f4b1
--- /dev/null
+++ b/google-analytics-data/get_metadata_by_property_id_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 get_metadata_by_property_id
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_get_metadata_by_property_id(capsys):
+ get_metadata_by_property_id.get_metadata_by_property_id(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Dimensions and metrics" in out
diff --git a/google-analytics-data/notebooks/advisor-chat.ipynb b/google-analytics-data/notebooks/advisor-chat.ipynb
new file mode 100644
index 0000000..607916a
--- /dev/null
+++ b/google-analytics-data/notebooks/advisor-chat.ipynb
@@ -0,0 +1,444 @@
+{
+ "cells": [
+ {
+ "id": "292c6ab2",
+ "cell_type": "markdown",
+ "source": [
+ "Project: /analytics/_project.yaml\n",
+ "Book: /analytics/_book.yaml\n",
+ "\n",
+ ""
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "aff86edc",
+ "cell_type": "markdown",
+ "source": [
+ "
"
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "8a3690ef",
+ "cell_type": "markdown",
+ "source": [],
+ "metadata": {}
+ },
+ {
+ "id": "ddd40ff6",
+ "cell_type": "markdown",
+ "source": [
+ "# **Programmatically using the Ask Advisor in Google Analytics to query and analyze your data**"
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "2092942a",
+ "cell_type": "markdown",
+ "source": [
+ "The [`chat`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat) method of the [Google Analytics Data API](https://developers.google.com/analytics/devguides/reporting/data/v1) (`v1alpha`) provides programmatic access to [Ask Advisor in Google Analytics](https://support.google.com/analytics/answer/16675569)—an AI-powered analytical assistant that helps you query, analyze, and diagnose your Google Analytics data using natural language.\n",
+ "\n",
+ "This notebook demonstrates how to use the [`google-analytics-data`](https://pypi.org/project/google-analytics-data/) Python client library (`AlphaAnalyticsDataClient`) to interact with Ask Advisor:\n",
+ "\n",
+ "\n",
+ " - Configure the Colab environment
\n",
+ " - Install and initialize the Python client
\n",
+ " - Configure your GA property ID
\n",
+ " - Example 1: Single-turn query with quota tracking
\n",
+ " - Parse and render structured response blocks
\n",
+ " - Example 2: Multi-turn conversational diagnostic
\n",
+ " - Interactive Ask Advisor assistant
\n",
+ "
\n",
+ "\n",
+ "> **Important:** This product uses AI and may display inaccurate info. Your chat activity may be used to improve the product and your use is subject to Google's [Terms](https://policies.google.com/terms), [AI Use Policy](https://policies.google.com/terms/generative-ai/use-policy), and [Privacy Policy](https://policies.google.com/privacy)."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "11c11d60",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 0: Configure the Colab environment\n",
+ "\n",
+ "To run this notebook in Google Colab, configure [Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/application-default-credentials) in the Colab runtime:\n",
+ "\n",
+ "1. Grant your user credentials the `https://www.googleapis.com/auth/analytics.chatbot.read` scope using `gcloud auth application-default login`.\n",
+ "2. Set a [Google Cloud quota project](https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds) that has the [Google Analytics Data API enabled](https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com) using `gcloud auth application-default set-quota-project`.\n",
+ "\n",
+ "> **Need a Google Cloud project?** If you don't already have a Google Cloud project with the Data API enabled, open the 1-click [Enable the Google Analytics Data API](https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com) console wizard. It will create a project (default name \"Quickstart\") or let you select an existing one and enable the API automatically. Then copy the project ID and enter it below.\n",
+ "\n",
+ "> **Note:** This step is only required to set up the temporary Google Colab VM environment (since Colab's built-in `google.colab.auth.authenticate_user()` helper only requests default Google Cloud scopes). When running outside of Colab, see [Before you begin](https://developers.google.com/analytics/devguides/reporting/data/v1/advisor-basics#before-you-begin) to configure credentials in your local or server environment.\n",
+ "\n",
+ "Enter your Google Cloud `PROJECT_ID` below, run the cell, open the printed authorization URL, sign in with a Google account that has [access to a Google Analytics property](https://support.google.com/analytics/answer/9305788), and paste the verification code when prompted."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "db497e28",
+ "cell_type": "code",
+ "source": [
+ "# @title Colab Authentication and Quota Project Setup\n",
+ "PROJECT_ID = \"YOUR_PROJECT_ID\" # @param {type:\"string\"}\n",
+ "\n",
+ "if not PROJECT_ID.strip() or PROJECT_ID == \"YOUR_PROJECT_ID\":\n",
+ " raise ValueError(\n",
+ " \"Please enter your Google Cloud project ID. If you need a project, \"\n",
+ " \"open the 1-click wizard at https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com \"\n",
+ " \"to create a project and enable the Google Analytics Data API.\"\n",
+ " )\n",
+ "\n",
+ "# 1. Authenticate the Colab environment with the Analytics Chatbot scope\n",
+ "!gcloud auth application-default login --no-launch-browser --scopes=\"https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/analytics.chatbot.read\"\n",
+ "\n",
+ "# 2. Set the Google Cloud quota project for Application Default Credentials\n",
+ "!gcloud auth application-default set-quota-project {PROJECT_ID}"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "4c27c1e9",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 1: Install and initialize the Python client\n",
+ "\n",
+ "Install the [`google-analytics-data`](https://pypi.org/project/google-analytics-data/) Python client library and initialize `AlphaAnalyticsDataClient` from `google.analytics.data_v1alpha`. The client automatically detects and uses the Application Default Credentials configured in your environment."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "e3d27f74",
+ "cell_type": "code",
+ "source": [
+ "%pip install --upgrade -q google-analytics-data\n",
+ "\n",
+ "from google.analytics import data_v1alpha\n",
+ "\n",
+ "# Create a client using Application Default Credentials\n",
+ "client = data_v1alpha.AlphaAnalyticsDataClient()\n",
+ "print(\"AlphaAnalyticsDataClient initialized successfully.\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "84b85a94",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 2: Configure your GA4 property ID\n",
+ "\n",
+ "Enter your numeric Google Analytics 4 Property ID below. You can find your Property ID in the [Google Analytics UI](https://analytics.google.com/) under **Admin > Property settings > Property details > Property ID**."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "d63017b0",
+ "cell_type": "code",
+ "source": [
+ "# @title GA4 Property Settings\n",
+ "PROPERTY_ID = \"YOUR_PROPERTY_ID\" # @param {type:\"string\"}\n",
+ "\n",
+ "if PROPERTY_ID == \"YOUR_PROPERTY_ID\" or not PROPERTY_ID.strip():\n",
+ " raise ValueError(\"Please provide a valid numeric GA4 Property ID.\")\n",
+ "\n",
+ "property_resource = f\"properties/{PROPERTY_ID.strip()}\"\n",
+ "print(f\"Configured property resource: {property_resource}\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "3541b873",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 3: Example 1 — Single-turn query with quota tracking\n",
+ "\n",
+ "To start a new conversation, construct a [`ChatRequest`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#request-body) containing your `property` resource name and `user_query`. Set `return_property_quota=True` to inspect your remaining daily and hourly chat token balance.\n",
+ "\n",
+ "### Scenario: Revenue and Conversion Rate by Device\n",
+ "\n",
+ "Suppose you want to compare revenue and conversion rate across mobile and desktop devices over the past 30 days."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "a481966b",
+ "cell_type": "code",
+ "source": [
+ "# Initialize request arguments\n",
+ "request = data_v1alpha.ChatRequest(\n",
+ " property=property_resource,\n",
+ " user_query=(\n",
+ " \"Compare our revenue and conversion rate across mobile vs desktop\"\n",
+ " \" over the last 30 days.\"\n",
+ " ),\n",
+ " return_property_quota=True,\n",
+ ")\n",
+ "\n",
+ "# Make the request\n",
+ "response = client.chat(request=request)\n",
+ "\n",
+ "# Save the assigned session_id for follow-up questions\n",
+ "session_id = response.session_id\n",
+ "print(f\"Session ID: {session_id}\")\n",
+ "print(f\"Received {len(response.blocks)} response block(s).\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "04f2ffcb",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 4: Parse and render structured response blocks\n",
+ "\n",
+ "The [`ChatResponse`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#response-body) object contains:\n",
+ "\n",
+ "* `session_id`: A newly assigned session identifier that you can pass in follow-up turns.\n",
+ "* `blocks`: A list of [`ResponseBlock`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#ResponseBlock) items:\n",
+ " * `block.text`: Markdown-formatted narrative summary and analytical takeaways.\n",
+ " * `block.table`: A structured [`DataTable`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#DataTable) containing `headers` (column names and semantic `data_type` such as `string` or `float`) and `rows` (lists of `columns` with `.value`).\n",
+ "* `property_quota`: The property's [`PropertyChatQuota`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#PropertyChatQuota) details (`tokens_per_day` and `tokens_per_hour`) when `return_property_quota=True`.\n",
+ "\n",
+ "Let's define a helper function to render `text` blocks as Markdown, convert `table` blocks into `pandas.DataFrame` objects, and display quota usage."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "f0694b89",
+ "cell_type": "code",
+ "source": [
+ "from IPython.display import Markdown, display\n",
+ "import pandas as pd\n",
+ "\n",
+ "\n",
+ "def render_chat_response(chat_response: data_v1alpha.ChatResponse) -> None:\n",
+ " \"\"\"Renders narrative text, data tables, and quota usage from a ChatResponse.\"\"\"\n",
+ " for block in chat_response.blocks:\n",
+ " if block.text:\n",
+ " display(Markdown(block.text))\n",
+ " elif block.table and (block.table.headers or block.table.rows):\n",
+ " headers = [h.header for h in block.table.headers]\n",
+ " rows = [[col.value for col in row.columns] for row in block.table.rows]\n",
+ " df = pd.DataFrame(rows, columns=headers)\n",
+ " display(df)\n",
+ "\n",
+ " if (\n",
+ " chat_response.property_quota\n",
+ " and chat_response.property_quota.tokens_per_day\n",
+ " ):\n",
+ " daily = chat_response.property_quota.tokens_per_day\n",
+ " hourly = chat_response.property_quota.tokens_per_hour\n",
+ " display(\n",
+ " Markdown(\n",
+ " f\"**Chat Quota:** Daily consumed: `{daily.consumed:,}` \"\n",
+ " f\"(remaining: `{daily.remaining:,}`) | \"\n",
+ " f\"Hourly consumed: `{hourly.consumed:,}` \"\n",
+ " f\"(remaining: `{hourly.remaining:,}`)\"\n",
+ " )\n",
+ " )\n",
+ "\n",
+ "\n",
+ "# Render the response from Example 1\n",
+ "render_chat_response(response)"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "08ef5c71",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 5: Example 2 — Multi-turn conversational diagnostic\n",
+ "\n",
+ "To ask a follow-up question while preserving conversation history, pass the `session_id` returned by the previous response in your next [`ChatRequest`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat#request-body).\n",
+ "\n",
+ "### Scenario: Compare with the previous period\n",
+ "\n",
+ "Following up on the device comparison above, use Ask Advisor to compare the results with the same period in the previous month."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "5df9957a",
+ "cell_type": "code",
+ "source": [
+ "# Initialize follow-up request with session_id from the previous turn\n",
+ "follow_up_request = data_v1alpha.ChatRequest(\n",
+ " property=property_resource,\n",
+ " session_id=session_id,\n",
+ " user_query=\"Compare results with the same period in the previous month.\",\n",
+ " return_property_quota=True,\n",
+ ")\n",
+ "\n",
+ "# Make the follow-up request\n",
+ "follow_up_response = client.chat(request=follow_up_request)\n",
+ "session_id = follow_up_response.session_id\n",
+ "\n",
+ "# Render the follow-up response\n",
+ "render_chat_response(follow_up_response)"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "806b1b35",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 6: Interactive Ask Advisor assistant\n",
+ "\n",
+ "Use the interactive form cell below to ask custom questions about your GA4 property. Check `reset_conversation` if you want to start a new session."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "6ce87515",
+ "cell_type": "code",
+ "source": [
+ "# @title Query Ask Advisor\n",
+ "user_query = \"What were our top traffic channels last week?\" # @param {type:\"string\"}\n",
+ "reset_conversation = False # @param {type:\"boolean\"}\n",
+ "\n",
+ "if reset_conversation:\n",
+ " session_id = \"\"\n",
+ " print(\"Started a new conversation session.\")\n",
+ "\n",
+ "chat_request = data_v1alpha.ChatRequest(\n",
+ " property=property_resource,\n",
+ " user_query=user_query,\n",
+ " session_id=session_id or \"\",\n",
+ " return_property_quota=True,\n",
+ ")\n",
+ "\n",
+ "chat_response = client.chat(request=chat_request)\n",
+ "session_id = chat_response.session_id\n",
+ "render_chat_response(chat_response)"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "b573f09c",
+ "cell_type": "markdown",
+ "source": [
+ "## Additional resources\n",
+ "\n",
+ "* [Using the Ask Advisor to query and analyze your data](https://developers.google.com/analytics/devguides/reporting/data/v1/advisor-basics)\n",
+ "* [`properties.chat` REST API Reference (`v1alpha`)](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/chat)\n",
+ "* [Google Analytics Data API Quotas](https://developers.google.com/analytics/devguides/reporting/data/v1/quotas)\n",
+ "* [Python Client Library Reference (`google-analytics-data`)](https://googleapis.dev/python/analyticsdata/latest/index.html)"
+ ],
+ "metadata": {}
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "name": "advisor-chat.ipynb",
+ "toc_visible": true,
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/google-analytics-data/notebooks/report-tasks.ipynb b/google-analytics-data/notebooks/report-tasks.ipynb
new file mode 100644
index 0000000..d28e919
--- /dev/null
+++ b/google-analytics-data/notebooks/report-tasks.ipynb
@@ -0,0 +1,606 @@
+{
+ "cells": [
+ {
+ "id": "c00e2ef9",
+ "cell_type": "markdown",
+ "source": [
+ "Project: /analytics/_project.yaml\n",
+ "Book: /analytics/_book.yaml\n",
+ "\n",
+ ""
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "cc278867",
+ "cell_type": "markdown",
+ "source": [
+ ""
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "2b909cb0",
+ "cell_type": "markdown",
+ "source": [],
+ "metadata": {}
+ },
+ {
+ "id": "ad386b33",
+ "cell_type": "markdown",
+ "source": [
+ "# **Creating asynchronous reports with report tasks in the Google Analytics Data API**"
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "f717ccd6",
+ "cell_type": "markdown",
+ "source": [
+ "[Report tasks](https://developers.google.com/analytics/devguides/reporting/data/v1/report-tasks) in the [Google Analytics Data API](https://developers.google.com/analytics/devguides/reporting/data/v1) (`v1alpha`) let you start a long-running asynchronous request to create a customized report of your Google Analytics event data. Instead of waiting for a report in a single synchronous call, you create a report task, check its readiness state, and then query the generated report once it's ready.\n",
+ "\n",
+ "A report task created by one user can be listed and queried by all users with read access to the Google Analytics property. A generated report is available for 72 hours after it's ready. After this period, the report task resource and its contents are automatically deleted.\n",
+ "\n",
+ "This notebook demonstrates how to use the [`google-analytics-data`](https://pypi.org/project/google-analytics-data/) Python client library (`AlphaAnalyticsDataClient`) to work with report tasks:\n",
+ "\n",
+ "\n",
+ " - Configure the Colab environment
\n",
+ " - Install and initialize the Python client
\n",
+ " - Configure your GA property ID
\n",
+ " - Create a report task
\n",
+ " - Wait for the report task to become ready
\n",
+ " - Retrieve the generated report
\n",
+ " - List report tasks for a property
\n",
+ " - Interactive report task builder
\n",
+ "
\n",
+ "\n",
+ "> **Note:** Report tasks are available in the [`v1alpha`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks) version of the Data API only. Alpha features may change in backward-incompatible ways."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "3f1444bd",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 0: Configure the Colab environment\n",
+ "\n",
+ "To run this notebook in Google Colab, configure [Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/application-default-credentials) with the `https://www.googleapis.com/auth/analytics.readonly` scope and a [Google Cloud quota project](https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds) that has the [Google Analytics Data API enabled](https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com).\n",
+ "\n",
+ "Choose an `AUTH_METHOD` in the form below based on your environment:\n",
+ "\n",
+ "* **`User Account (gcloud ADC)`** *(default)*: Authenticates with your Google user account via `gcloud auth application-default login` and sets `PROJECT_ID` as the quota project. Sign in with an account that has [access to your Google Analytics property](https://support.google.com/analytics/answer/9305788).\n",
+ "* **`Service Account Key JSON`**: Prompts you to upload a service account key `.json` file via `google.colab.auth.authenticate_service_account()`. Make sure the service account email has been granted [Viewer access to the Google Analytics property](https://support.google.com/analytics/answer/9305788).\n",
+ "* **`Service Account Impersonation`**: [Keyless authentication](https://docs.cloud.google.com/docs/authentication/use-service-account-impersonation) using `--impersonate-service-account` with `SERVICE_ACCOUNT_EMAIL`. Avoids requesting `analytics.readonly` on `gcloud`'s default OAuth client ID (requires `roles/iam.serviceAccountTokenCreator` on the service account and Viewer access on the GA property).\n",
+ "* **`Custom OAuth Client JSON`**: Prompts you to upload your own Desktop OAuth `client_secret.json` ([create one in Cloud Console](https://console.cloud.google.com/apis/credentials)) and passes `--client-id-file` to `gcloud` (recommended if your organization blocks `analytics.readonly` on `gcloud`'s default client ID; see [ADC scope troubleshooting](https://cloud.google.com/docs/authentication/troubleshoot-adc#access_blocked_when_using_scopes)).\n",
+ "\n",
+ "> **Need a Google Cloud project?** If you don't already have a Google Cloud project with the Data API enabled, open the 1-click [Enable the Google Analytics Data API](https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com) console wizard. It will create a project or let you select an existing one and enable the API automatically. Then copy the project ID and enter it below.\n",
+ "\n",
+ "> **Note:** This step is only required to set up the temporary Google Colab VM environment (since Colab's built-in `google.colab.auth.authenticate_user()` helper only requests default Google Cloud scopes). When running outside of Colab, see the [API quickstart](https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries) to configure credentials in your local or server environment."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "104a46a2",
+ "cell_type": "code",
+ "source": [
+ "#@title Colab Authentication and Quota Project Setup { display-mode: \"form\" }\n",
+ "AUTH_METHOD = \"User Account (gcloud ADC)\" #@param [\"User Account (gcloud ADC)\", \"Service Account Key JSON\", \"Service Account Impersonation\", \"Custom OAuth Client JSON\"]\n",
+ "PROJECT_ID = \"YOUR_PROJECT_ID\" #@param {type:\"string\"}\n",
+ "SERVICE_ACCOUNT_EMAIL = \"\" #@param {type:\"string\"}\n",
+ "\n",
+ "SCOPES = \"https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/analytics.readonly\"\n",
+ "\n",
+ "\n",
+ "def _require_project_id() -> str:\n",
+ " project_id = PROJECT_ID.strip()\n",
+ " if not project_id or project_id == \"YOUR_PROJECT_ID\":\n",
+ " raise ValueError(\n",
+ " \"Please enter your Google Cloud project ID. If you need a project, \"\n",
+ " \"open the 1-click wizard at \"\n",
+ " \"https://console.cloud.google.com/flows/enableapi?apiid=analyticsdata.googleapis.com \"\n",
+ " \"to create a project and enable the Google Analytics Data API.\"\n",
+ " )\n",
+ " return project_id\n",
+ "\n",
+ "\n",
+ "if AUTH_METHOD == \"User Account (gcloud ADC)\":\n",
+ " project_id = _require_project_id()\n",
+ " !gcloud auth application-default login --no-launch-browser --scopes=\"{SCOPES}\"\n",
+ " !gcloud auth application-default set-quota-project {project_id}\n",
+ "\n",
+ "elif AUTH_METHOD == \"Service Account Key JSON\":\n",
+ " from google.colab import auth\n",
+ "\n",
+ " auth.authenticate_service_account()\n",
+ "\n",
+ "elif AUTH_METHOD == \"Service Account Impersonation\":\n",
+ " project_id = _require_project_id()\n",
+ " sa_email = SERVICE_ACCOUNT_EMAIL.strip()\n",
+ " if not sa_email:\n",
+ " raise ValueError(\n",
+ " \"Please enter SERVICE_ACCOUNT_EMAIL for Service Account Impersonation.\"\n",
+ " )\n",
+ " !gcloud auth application-default login --no-launch-browser --impersonate-service-account=\"{sa_email}\" --scopes=\"{SCOPES}\"\n",
+ " !gcloud config set project {project_id}\n",
+ "\n",
+ "elif AUTH_METHOD == \"Custom OAuth Client JSON\":\n",
+ " from google.colab import files\n",
+ "\n",
+ " project_id = _require_project_id()\n",
+ " print(\"Upload your OAuth Desktop client JSON file (client_secret.json):\")\n",
+ " uploaded = files.upload()\n",
+ " if not uploaded:\n",
+ " raise ValueError(\"No OAuth client JSON file was uploaded.\")\n",
+ " client_id_file = next(iter(uploaded))\n",
+ " !gcloud auth application-default login --no-browser --client-id-file=\"{client_id_file}\" --scopes=\"{SCOPES}\"\n",
+ " !gcloud auth application-default set-quota-project {project_id}"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "collapsed": true,
+ "jupyter": {
+ "source_hidden": true
+ }
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "7b4b439f",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 1: Install and initialize the Python client\n",
+ "\n",
+ "Install the [`google-analytics-data`](https://pypi.org/project/google-analytics-data/) Python client library and initialize `AlphaAnalyticsDataClient` from `google.analytics.data_v1alpha`. The client automatically detects and uses the Application Default Credentials configured in your environment."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "d13e0f0f",
+ "cell_type": "code",
+ "source": [
+ "%pip install --upgrade -q google-analytics-data\n",
+ "\n",
+ "from google.analytics import data_v1alpha\n",
+ "\n",
+ "# Create a client using Application Default Credentials\n",
+ "client = data_v1alpha.AlphaAnalyticsDataClient()\n",
+ "print(\"AlphaAnalyticsDataClient initialized successfully.\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "339df1cc",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 2: Configure your GA4 property ID\n",
+ "\n",
+ "Enter your numeric Google Analytics 4 Property ID below. You can find your Property ID in the [Google Analytics UI](https://analytics.google.com/) under **Admin > Property settings > Property details > Property ID**."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "be2fabe4",
+ "cell_type": "code",
+ "source": [
+ "# @title GA Property Settings\n",
+ "PROPERTY_ID = \"YOUR_PROPERTY_ID\" # @param {type:\"string\"}\n",
+ "\n",
+ "if PROPERTY_ID == \"YOUR_PROPERTY_ID\" or not PROPERTY_ID.strip():\n",
+ " raise ValueError(\"Please provide a valid numeric GA Property ID.\")\n",
+ "\n",
+ "property_resource = f\"properties/{PROPERTY_ID.strip()}\"\n",
+ "print(f\"Configured property resource: {property_resource}\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "e96bd593",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 3: Create a report task\n",
+ "\n",
+ "To create a report task, call the [`create_report_task`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks/create) method with a [`ReportTask`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks#ReportTask) object. The task's `report_definition` describes the customized report, and its structure is similar to the report definition used by the [Core Reporting methods](https://developers.google.com/analytics/devguides/reporting/data/v1/basics): `dimensions`, `metrics`, `date_ranges`, filters, `order_bys`, `offset`, `limit`, and so on.\n",
+ "\n",
+ "`create_report_task` returns a [long-running operation](https://google.aip.dev/151). Calling `operation.result()` returns the newly created `ReportTask`, whose `name` field (such as `properties/1234567/reportTasks/123`) identifies the task in subsequent requests. At this point, the report is usually still in the `CREATING` state.\n",
+ "\n",
+ "### Scenario: Active users and sessions by country and device\n",
+ "\n",
+ "Suppose you want to build a report of active users and sessions broken down by country and device category over the last 28 days, sorted by active users."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "cf4737c5",
+ "cell_type": "code",
+ "source": [
+ "# Define the customized report\n",
+ "report_definition = data_v1alpha.ReportTask.ReportDefinition(\n",
+ " dimensions=[\n",
+ " data_v1alpha.Dimension(name=\"country\"),\n",
+ " data_v1alpha.Dimension(name=\"deviceCategory\"),\n",
+ " ],\n",
+ " metrics=[\n",
+ " data_v1alpha.Metric(name=\"activeUsers\"),\n",
+ " data_v1alpha.Metric(name=\"sessions\"),\n",
+ " ],\n",
+ " date_ranges=[\n",
+ " data_v1alpha.DateRange(start_date=\"28daysAgo\", end_date=\"yesterday\")\n",
+ " ],\n",
+ " order_bys=[\n",
+ " data_v1alpha.OrderBy(\n",
+ " metric=data_v1alpha.OrderBy.MetricOrderBy(metric_name=\"activeUsers\"),\n",
+ " desc=True,\n",
+ " )\n",
+ " ],\n",
+ ")\n",
+ "\n",
+ "# Initialize request arguments\n",
+ "request = data_v1alpha.CreateReportTaskRequest(\n",
+ " parent=property_resource,\n",
+ " report_task=data_v1alpha.ReportTask(report_definition=report_definition),\n",
+ ")\n",
+ "\n",
+ "# Make the request. The method returns a long-running operation.\n",
+ "operation = client.create_report_task(request=request)\n",
+ "report_task = operation.result()\n",
+ "\n",
+ "# Save the report task name for subsequent requests\n",
+ "report_task_name = report_task.name\n",
+ "print(f\"Report task name: {report_task_name}\")\n",
+ "print(f\"Initial state: {report_task.report_metadata.state.name}\")"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "3f06e706",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 4: Wait for the report task to become ready\n",
+ "\n",
+ "It may take several minutes to generate a report after the `create_report_task` call. To check the readiness state of a report task, call the [`get_report_task`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks/get) method with the report task name.\n",
+ "\n",
+ "The readiness status is returned in the [`report_metadata.state`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks#ReportTask.FIELDS.state) field. Once report generation is complete, the state changes from `CREATING` to `ACTIVE` (or to `FAILED` if the report can't be generated, in which case `report_metadata.error_message` explains why).\n",
+ "\n",
+ "The [`report_metadata`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks#ReportTask.FIELDS.reportMetadata) field also contains high-level information about the generated report:\n",
+ "\n",
+ "* `begin_creating_time`: The time when report creation started.\n",
+ "* `creation_quota_tokens_charged`: The total quota tokens charged during report creation.\n",
+ "* `task_row_count`: The number of rows in the generated report.\n",
+ "* `total_row_count`: The total number of rows available in Google Analytics storage. If it's larger than `task_row_count`, you can create another report task with a different `offset` to retrieve the remaining rows.\n",
+ "\n",
+ "Let's define a helper function that polls `get_report_task` until the report task leaves the `CREATING` state."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "96f7a0a6",
+ "cell_type": "code",
+ "source": [
+ "import time\n",
+ "\n",
+ "State = data_v1alpha.ReportTask.ReportMetadata.State\n",
+ "\n",
+ "\n",
+ "def wait_for_report_task(\n",
+ " name: str, poll_interval_seconds: int = 10, timeout_seconds: int = 900\n",
+ ") -> data_v1alpha.ReportTask:\n",
+ " \"\"\"Polls a report task until it is ACTIVE, and returns the ReportTask.\"\"\"\n",
+ " deadline = time.monotonic() + timeout_seconds\n",
+ " while True:\n",
+ " task = client.get_report_task(\n",
+ " request=data_v1alpha.GetReportTaskRequest(name=name)\n",
+ " )\n",
+ " state = task.report_metadata.state\n",
+ " print(f\"{time.strftime('%H:%M:%S')} {name}: {state.name}\")\n",
+ "\n",
+ " if state == State.ACTIVE:\n",
+ " return task\n",
+ " if state == State.FAILED:\n",
+ " raise RuntimeError(\n",
+ " f\"Report task failed: {task.report_metadata.error_message}\"\n",
+ " )\n",
+ " if time.monotonic() > deadline:\n",
+ " raise TimeoutError(\n",
+ " f\"Report task is still {state.name} after {timeout_seconds} seconds.\"\n",
+ " \" Re-run this cell later to check again.\"\n",
+ " )\n",
+ " time.sleep(poll_interval_seconds)\n",
+ "\n",
+ "\n",
+ "def print_report_metadata(task: data_v1alpha.ReportTask) -> None:\n",
+ " \"\"\"Prints high-level information about a generated report.\"\"\"\n",
+ " metadata = task.report_metadata\n",
+ " print(f\"State: {metadata.state.name}\")\n",
+ " print(f\"Began creating: {metadata.begin_creating_time}\")\n",
+ " print(f\"Quota tokens charged: {metadata.creation_quota_tokens_charged}\")\n",
+ " print(f\"Task row count: {metadata.task_row_count:,}\")\n",
+ " print(f\"Total row count: {metadata.total_row_count:,}\")\n",
+ "\n",
+ "\n",
+ "# Wait for the report task from Step 3 to become ready\n",
+ "report_task = wait_for_report_task(report_task_name)\n",
+ "print_report_metadata(report_task)"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "aca9b10d",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 5: Retrieve the generated report\n",
+ "\n",
+ "Once the report task is `ACTIVE`, call the [`query_report_task`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks/query) method with the report task name to retrieve the generated report. The method returns an error if the report task isn't `ACTIVE` yet.\n",
+ "\n",
+ "The [`QueryReportTaskResponse`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks/query#response-body) has the same shape as a Core Reporting response: `dimension_headers`, `metric_headers`, `rows` (each with `dimension_values` and `metric_values`), `row_count`, and `metadata`.\n",
+ "\n",
+ "Use the optional `offset` and `limit` parameters to page through large reports. If unspecified, up to 10,000 rows are returned per request. The helper below pages through the entire report and converts it into a `pandas.DataFrame`."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "cf41e8bc",
+ "cell_type": "code",
+ "source": [
+ "from IPython.display import display\n",
+ "import pandas as pd\n",
+ "\n",
+ "\n",
+ "def query_report_task_to_dataframe(\n",
+ " name: str, page_size: int = 10000\n",
+ ") -> pd.DataFrame:\n",
+ " \"\"\"Retrieves all rows of a generated report as a pandas DataFrame.\"\"\"\n",
+ " headers = []\n",
+ " rows = []\n",
+ " offset = 0\n",
+ " while True:\n",
+ " response = client.query_report_task(\n",
+ " request=data_v1alpha.QueryReportTaskRequest(\n",
+ " name=name, offset=offset, limit=page_size\n",
+ " )\n",
+ " )\n",
+ " if not headers:\n",
+ " headers = [h.name for h in response.dimension_headers] + [\n",
+ " h.name for h in response.metric_headers\n",
+ " ]\n",
+ " rows.extend(\n",
+ " [v.value for v in row.dimension_values]\n",
+ " + [v.value for v in row.metric_values]\n",
+ " for row in response.rows\n",
+ " )\n",
+ " offset += len(response.rows)\n",
+ " if not response.rows or offset >= response.row_count:\n",
+ " break\n",
+ "\n",
+ " print(\n",
+ " f\"Retrieved {len(rows):,} row(s). Currency: \"\n",
+ " f\"{response.metadata.currency_code}, time zone: \"\n",
+ " f\"{response.metadata.time_zone}\"\n",
+ " )\n",
+ " return pd.DataFrame(rows, columns=headers)\n",
+ "\n",
+ "\n",
+ "# Retrieve the report generated in Step 4\n",
+ "df = query_report_task_to_dataframe(report_task_name)\n",
+ "display(df.head(20))"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "f04f897f",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 6: List report tasks for a property\n",
+ "\n",
+ "To list all report tasks for a property, call the [`list_report_tasks`](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks/list) method. The client library returns a pager that automatically fetches subsequent pages as you iterate. Because report tasks are shared, the list includes tasks created by all users with access to the property during the last 72 hours."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "617f0429",
+ "cell_type": "code",
+ "source": [
+ "# Make the request. The pager handles page tokens automatically.\n",
+ "pager = client.list_report_tasks(\n",
+ " request=data_v1alpha.ListReportTasksRequest(parent=property_resource)\n",
+ ")\n",
+ "\n",
+ "tasks_df = pd.DataFrame(\n",
+ " [\n",
+ " {\n",
+ " \"name\": task.name,\n",
+ " \"state\": task.report_metadata.state.name,\n",
+ " \"begin_creating_time\": task.report_metadata.begin_creating_time,\n",
+ " \"dimensions\": \", \".join(\n",
+ " d.name for d in task.report_definition.dimensions\n",
+ " ),\n",
+ " \"metrics\": \", \".join(m.name for m in task.report_definition.metrics),\n",
+ " \"task_row_count\": task.report_metadata.task_row_count,\n",
+ " }\n",
+ " for task in pager\n",
+ " ]\n",
+ ")\n",
+ "display(tasks_df)"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "ada0ccd4",
+ "cell_type": "markdown",
+ "source": [
+ "\n",
+ "## Step 7: Interactive report task builder\n",
+ "\n",
+ "Use the interactive form cell below to create a custom report task for your GA4 property. Enter comma-separated [dimension and metric API names](https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema), a date range, and a row limit. The cell creates the report task, waits for it to become ready, and displays the generated report."
+ ],
+ "metadata": {}
+ },
+ {
+ "id": "418d10a5",
+ "cell_type": "code",
+ "source": [
+ "# @title Create a Custom Report Task\n",
+ "dimensions = \"date, sessionDefaultChannelGroup\" # @param {type:\"string\"}\n",
+ "metrics = \"activeUsers, newUsers, engagementRate\" # @param {type:\"string\"}\n",
+ "start_date = \"7daysAgo\" # @param {type:\"string\"}\n",
+ "end_date = \"yesterday\" # @param {type:\"string\"}\n",
+ "row_limit = 10000 # @param {type:\"integer\"}\n",
+ "\n",
+ "\n",
+ "def _split(names: str) -> list[str]:\n",
+ " return [name.strip() for name in names.split(\",\") if name.strip()]\n",
+ "\n",
+ "\n",
+ "custom_request = data_v1alpha.CreateReportTaskRequest(\n",
+ " parent=property_resource,\n",
+ " report_task=data_v1alpha.ReportTask(\n",
+ " report_definition=data_v1alpha.ReportTask.ReportDefinition(\n",
+ " dimensions=[data_v1alpha.Dimension(name=n) for n in _split(dimensions)],\n",
+ " metrics=[data_v1alpha.Metric(name=n) for n in _split(metrics)],\n",
+ " date_ranges=[\n",
+ " data_v1alpha.DateRange(start_date=start_date, end_date=end_date)\n",
+ " ],\n",
+ " limit=row_limit,\n",
+ " )\n",
+ " ),\n",
+ ")\n",
+ "\n",
+ "custom_task = client.create_report_task(request=custom_request).result()\n",
+ "custom_task = wait_for_report_task(custom_task.name)\n",
+ "print_report_metadata(custom_task)\n",
+ "display(query_report_task_to_dataframe(custom_task.name))"
+ ],
+ "metadata": {},
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "id": "2d4f2c82",
+ "cell_type": "markdown",
+ "source": [
+ "## Additional resources\n",
+ "\n",
+ "* [Report tasks fundamentals](https://developers.google.com/analytics/devguides/reporting/data/v1/report-tasks)\n",
+ "* [`properties.reportTasks` REST API Reference (`v1alpha`)](https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties.reportTasks)\n",
+ "* [API Dimensions & Metrics](https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema)\n",
+ "* [Google Analytics Data API Quotas](https://developers.google.com/analytics/devguides/reporting/data/v1/quotas)\n",
+ "* [Python Client Library Reference (`google-analytics-data`)](https://googleapis.dev/python/analyticsdata/latest/index.html)"
+ ],
+ "metadata": {}
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "name": "report-tasks.ipynb",
+ "toc_visible": true,
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/google-analytics-data/noxfile.py b/google-analytics-data/noxfile.py
new file mode 100644
index 0000000..1581f3c
--- /dev/null
+++ b/google-analytics-data/noxfile.py
@@ -0,0 +1,302 @@
+# 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 annotations
+from __future__ import print_function
+
+from collections.abc import Callable
+import glob
+import os
+from pathlib import Path
+import sys
+
+import nox
+
+
+# WARNING - WARNING - WARNING - WARNING - WARNING
+# WARNING - WARNING - WARNING - WARNING - WARNING
+# BE CAREFUL WHEN EDITING THIS FILE!
+# 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", "3.7", "3.9", "3.10", "3.11"],
+ # 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',
+ # If you need to use a specific version of pip,
+ # change pip_version_override to the string representation
+ # of the version number, for example, "20.2.4"
+ "pip_version_override": None,
+ # 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
+
+
+# All versions used to tested samples.
+ALL_VERSIONS = ["2.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
+
+# 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))
+
+# Error if a python version is missing
+nox.options.error_on_missing_interpreters = True
+
+#
+# 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 ensure 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:
+# ANN101: missing type annotation for self in method
+# 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=ANN101,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:
+ # check for presence of tests
+ test_list = glob.glob("*_test.py") + glob.glob("test_*.py")
+ test_list.extend(glob.glob("tests"))
+
+ if len(test_list) == 0:
+ print("No tests found, skipping directory.")
+ return
+
+ if TEST_CONFIG["pip_version_override"]:
+ pip_version = TEST_CONFIG["pip_version_override"]
+ session.install(f"pip=={pip_version}")
+ else:
+ session.install("--upgrade", "pip")
+
+ """Runs py.test for a particular project."""
+ concurrent_args = []
+ if os.path.exists("requirements.txt"):
+ with open("requirements.txt") as rfile:
+ packages = rfile.read()
+ if os.path.exists("constraints.txt"):
+ session.install(
+ "-r",
+ "requirements.txt",
+ "-c",
+ "constraints.txt",
+ "--only-binary",
+ ":all",
+ )
+ elif "pyspark" in packages:
+ session.install("-r", "requirements.txt", "--use-pep517")
+ else:
+ session.install("-r", "requirements.txt", "--only-binary", ":all")
+
+ if os.path.exists("requirements-test.txt"):
+ with open("requirements-test.txt") as rtfile:
+ packages += rtfile.read()
+ if os.path.exists("constraints-test.txt"):
+ session.install(
+ "-r",
+ "requirements-test.txt",
+ "-c",
+ "constraints-test.txt",
+ "--only-binary",
+ ":all",
+ )
+ else:
+ session.install("-r", "requirements-test.txt", "--only-binary", ":all")
+
+ if INSTALL_LIBRARY_FROM_SOURCE:
+ session.install("-e", _get_repo_root())
+
+ if post_install:
+ post_install(session)
+
+ if "pytest-parallel" in packages:
+ concurrent_args.extend(["--workers", "auto", "--tests-per-worker", "auto"])
+ elif "pytest-xdist" in packages:
+ concurrent_args.extend(["-n", "auto"])
+
+ session.run(
+ "pytest",
+ *(PYTEST_COMMON_ARGS + session.posargs + concurrent_args),
+ # 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() -> str | None:
+ """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/google-analytics-data/noxfile_config.py b/google-analytics-data/noxfile_config.py
new file mode 100644
index 0000000..33d438c
--- /dev/null
+++ b/google-analytics-data/noxfile_config.py
@@ -0,0 +1,34 @@
+# 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
+
+TEST_CONFIG_OVERRIDE = {
+ # You can opt out from the test for specific Python versions.
+ "ignored_versions": ["2.7", "3.8", "3.9"],
+ # 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.
+ #
+ # Adds the GA_TEST_PROPERTY_ID required by tests for Google Analytics
+ # Data samples. Uses a specific test property by default, but can
+ # be overridden by setting this environment variable before running
+ # nox.
+ "envs": {"GA_TEST_PROPERTY_ID": os.getenv("GA_TEST_PROPERTY_ID", "222596558")},
+}
diff --git a/google-analytics-data/quickstart.py b/google-analytics-data/quickstart.py
new file mode 100644
index 0000000..f1e3538
--- /dev/null
+++ b/google-analytics-data/quickstart.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample quickstart application.
+This application demonstrates the usage of the Analytics Data API using
+service account credentials.
+Before you start the application, please review the comments starting with
+"TODO(developer)" and update the code to use correct values.
+Usage:
+ pip3 install --upgrade google-analytics-data
+ python3 quickstart.py
+"""
+# [START analyticsdata_quickstart]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+
+def sample_run_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a simple report on a Google Analytics 4 property."""
+ # TODO(developer): Uncomment this variable and replace with your
+ # Google Analytics 4 property ID before running the sample.
+ # property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # [START analyticsdata_run_report_initialize]
+ # Using a default constructor instructs the client to use the credentials
+ # specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
+ client = BetaAnalyticsDataClient()
+ # [END analyticsdata_run_report_initialize]
+
+ # [START analyticsdata_run_report]
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="city")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2020-03-31", end_date="today")],
+ )
+ response = client.run_report(request)
+ # [END analyticsdata_run_report]
+
+ # [START analyticsdata_run_report_response]
+ print("Report result:")
+ for row in response.rows:
+ print(row.dimension_values[0].value, row.metric_values[0].value)
+ # [END analyticsdata_run_report_response]
+
+
+# [END analyticsdata_quickstart]
+
+
+if __name__ == "__main__":
+ sample_run_report()
diff --git a/google-analytics-data/quickstart_json_credentials.py b/google-analytics-data/quickstart_json_credentials.py
new file mode 100644
index 0000000..fb93cbd
--- /dev/null
+++ b/google-analytics-data/quickstart_json_credentials.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample quickstart application.
+
+This application demonstrates the usage of the Analytics Data API using
+service account credentials from a JSON file downloaded from
+the Google Cloud Console.
+
+Before you start the application, please review the comments starting with
+"TODO(developer)" and update the code to use correct values.
+
+Usage:
+ pip3 install --upgrade google-analytics-data
+ python3 quickstart_json_credentials.py
+"""
+# [START analyticsdata_json_credentials_quickstart]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+
+def sample_run_report(property_id="YOUR-GA4-PROPERTY-ID", credentials_json_path=""):
+ """Runs a simple report on a Google Analytics 4 property."""
+ # TODO(developer): Uncomment this variable and replace with your
+ # Google Analytics 4 property ID before running the sample.
+ # property_id = "YOUR-GA4-PROPERTY-ID"
+
+ # [START analyticsdata_json_credentials_initialize]
+ # TODO(developer): Uncomment this variable and replace with a valid path to
+ # the credentials.json file for your service account downloaded from the
+ # Cloud Console.
+ # credentials_json_path = "/path/to/credentials.json"
+
+ # Explicitly use service account credentials by specifying
+ # the private key file.
+ client = BetaAnalyticsDataClient.from_service_account_json(credentials_json_path)
+ # [END analyticsdata_json_credentials_initialize]
+
+ # [START analyticsdata_json_credentials_run_report]
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="city")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2020-03-31", end_date="today")],
+ )
+ response = client.run_report(request)
+ # [END analyticsdata_json_credentials_run_report]
+
+ print("Report result:")
+ for row in response.rows:
+ print(row.dimension_values[0].value, row.metric_values[0].value)
+
+
+# [END analyticsdata_json_credentials_quickstart]
+
+
+if __name__ == "__main__":
+ sample_run_report()
diff --git a/google-analytics-data/quickstart_json_credentials_test.py b/google-analytics-data/quickstart_json_credentials_test.py
new file mode 100644
index 0000000..06d7d1e
--- /dev/null
+++ b/google-analytics-data/quickstart_json_credentials_test.py
@@ -0,0 +1,29 @@
+# Copyright 2020 Google Inc. 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 quickstart_json_credentials
+
+
+def test_quickstart(capsys):
+ # Create a temporary service account credentials JSON file to be used by
+ # the test.
+ TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+ CREDENTIALS_JSON_PATH = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
+ quickstart_json_credentials.sample_run_report(
+ TEST_PROPERTY_ID, CREDENTIALS_JSON_PATH
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/quickstart_oauth2.py b/google-analytics-data/quickstart_oauth2.py
new file mode 100644
index 0000000..e8282cc
--- /dev/null
+++ b/google-analytics-data/quickstart_oauth2.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample quickstart application.
+This application demonstrates the usage of the Analytics Data API using
+OAuth2 credentials.
+Before you start the application, please review the comments starting with
+"TODO(developer)" and update the code to use correct values.
+Usage:
+ pip3 install --upgrade google-auth-oauthlib
+ pip3 install --upgrade google-analytics-data
+ python3 quickstart_oauth2.py
+"""
+# [START analyticsdata_oauth2_quickstart]
+from google.analytics.data import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+from google_auth_oauthlib import flow
+
+
+def sample_run_report(credentials=None, property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a simple report on a Google Analytics 4 property."""
+ # TODO(developer): Uncomment this variable and replace with your
+ # Google Analytics 4 property ID before running the sample.
+ # property_id = "YOUR-GA4-PROPERTY-ID"
+
+ client = BetaAnalyticsDataClient(credentials=credentials)
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="city")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2020-03-31", end_date="today")],
+ )
+
+ response = client.run_report(request)
+
+ print("Report result:")
+ for row in response.rows:
+ print(row.dimension_values[0].value, row.metric_values[0].value)
+
+
+def get_credentials():
+ """Creates an OAuth2 credentials instance."""
+ # [START analyticsdata_oauth2_initialize]
+ appflow = flow.InstalledAppFlow.from_client_secrets_file(
+ "client_secrets.json",
+ scopes=["https://www.googleapis.com/auth/analytics.readonly"],
+ )
+ # TODO(developer): Update the line below to set the `launch_browser` variable.
+ # The `launch_browser` boolean variable indicates if a local server is used
+ # as the callback URL in the auth flow. A value of `True` is recommended,
+ # but a local server does not work if accessing the application remotely,
+ # such as over SSH or from a remote Jupyter notebook.
+ launch_browser = True
+ if launch_browser:
+ appflow.run_local_server()
+ else:
+ appflow.run_console()
+ return appflow.credentials
+ # [END analyticsdata_oauth2_initialize]
+
+
+def main():
+ credentials = get_credentials()
+ sample_run_report(credentials)
+
+
+# [END analyticsdata_oauth2_quickstart]
+
+
+if __name__ == "__main__":
+ main()
diff --git a/google-analytics-data/quickstart_oauth2_test.py b/google-analytics-data/quickstart_oauth2_test.py
new file mode 100644
index 0000000..dcbdc19
--- /dev/null
+++ b/google-analytics-data/quickstart_oauth2_test.py
@@ -0,0 +1,24 @@
+# Copyright 2020 Google Inc. 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 quickstart_oauth2
+
+
+def test_quickstart(capsys):
+ TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+ quickstart_oauth2.sample_run_report(None, TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/quickstart_test.py b/google-analytics-data/quickstart_test.py
new file mode 100644
index 0000000..14c639d
--- /dev/null
+++ b/google-analytics-data/quickstart_test.py
@@ -0,0 +1,24 @@
+# Copyright 2020 Google Inc. 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 quickstart
+
+
+def test_quickstart(capsys):
+ TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+ quickstart.sample_run_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/requirements-test.txt b/google-analytics-data/requirements-test.txt
new file mode 100644
index 0000000..3fdf1e1
--- /dev/null
+++ b/google-analytics-data/requirements-test.txt
@@ -0,0 +1 @@
+pytest==9.2.0
diff --git a/google-analytics-data/requirements.txt b/google-analytics-data/requirements.txt
new file mode 100644
index 0000000..6f53d90
--- /dev/null
+++ b/google-analytics-data/requirements.txt
@@ -0,0 +1,2 @@
+google-analytics-data==0.23.3
+google-auth-oauthlib==1.5.0
\ No newline at end of file
diff --git a/google-analytics-data/run_batch_report.py b/google-analytics-data/run_batch_report.py
new file mode 100644
index 0000000..07cdf40
--- /dev/null
+++ b/google-analytics-data/run_batch_report.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the batch creation
+of multiple reports.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/batchRunReports
+for more information.
+"""
+# [START analyticsdata_run_batch_report]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ BatchRunReportsRequest,
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_batch_report(property_id)
+
+
+def run_batch_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a batch report on a Google Analytics 4 property."""
+ client = BetaAnalyticsDataClient()
+
+ request = BatchRunReportsRequest(
+ property=f"properties/{property_id}",
+ requests=[
+ RunReportRequest(
+ dimensions=[
+ Dimension(name="country"),
+ Dimension(name="region"),
+ Dimension(name="city"),
+ ],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2021-01-03", end_date="2021-01-09")],
+ ),
+ RunReportRequest(
+ dimensions=[Dimension(name="browser")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2021-01-01", end_date="2021-01-31")],
+ ),
+ ],
+ )
+ response = client.batch_run_reports(request)
+
+ print("Batch report results:")
+ for report in response.reports:
+ print_run_report_response(report)
+
+
+# [END analyticsdata_run_batch_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_batch_report_test.py b/google-analytics-data/run_batch_report_test.py
new file mode 100644
index 0000000..880c10b
--- /dev/null
+++ b/google-analytics-data/run_batch_report_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_batch_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_batch_report(capsys):
+ run_batch_report.run_batch_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Batch report result" in out
diff --git a/google-analytics-data/run_funnel_report.py b/google-analytics-data/run_funnel_report.py
new file mode 100644
index 0000000..937e3e8
--- /dev/null
+++ b/google-analytics-data/run_funnel_report.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+
+# Copyright 2022 Google Inc. 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 Data API sample application demonstrating the creation of
+a funnel report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1alpha/properties/runFunnelReport
+for more information.
+"""
+# [START analyticsdata_run_funnel_report]
+from google.analytics.data_v1alpha import AlphaAnalyticsDataClient
+from google.analytics.data_v1alpha.types import (
+ DateRange,
+ Dimension,
+ Funnel,
+ FunnelBreakdown,
+ FunnelEventFilter,
+ FunnelFieldFilter,
+ FunnelFilterExpression,
+ FunnelFilterExpressionList,
+ FunnelStep,
+ RunFunnelReportRequest,
+ StringFilter,
+)
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_funnel_report(property_id)
+
+
+def run_funnel_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a funnel query to build a report with 5 funnel steps.
+ Step 1: First open/visit (event name is `first_open` or `first_visit`).
+ Step 2: Organic visitors (`firstUserMedium` dimension contains the term
+ "organic").
+ Step 3: Session start (event name is `session_start`).
+ Step 4: Screen/Page view (event name is `screen_view` or `page_view`).
+ Step 5: Purchase (event name is `purchase` or `in_app_purchase`).
+
+ The report configuration reproduces the default funnel report provided in
+ the Funnel Exploration template of the Google Analytics UI.
+ See more at https://support.google.com/analytics/answer/9327974
+ """
+ client = AlphaAnalyticsDataClient()
+
+ request = RunFunnelReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
+ funnel_breakdown=FunnelBreakdown(
+ breakdown_dimension=Dimension(name="deviceCategory")
+ ),
+ funnel=Funnel(
+ steps=[
+ FunnelStep(
+ name="First open/visit",
+ filter_expression=FunnelFilterExpression(
+ or_group=FunnelFilterExpressionList(
+ expressions=[
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="first_open"
+ )
+ ),
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="first_visit"
+ )
+ ),
+ ]
+ )
+ ),
+ ),
+ FunnelStep(
+ name="Organic visitors",
+ filter_expression=FunnelFilterExpression(
+ funnel_field_filter=FunnelFieldFilter(
+ field_name="firstUserMedium",
+ string_filter=StringFilter(
+ match_type=StringFilter.MatchType.CONTAINS,
+ case_sensitive=False,
+ value="organic",
+ ),
+ )
+ ),
+ ),
+ FunnelStep(
+ name="Session start",
+ filter_expression=FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="session_start"
+ )
+ ),
+ ),
+ FunnelStep(
+ name="Screen/Page view",
+ filter_expression=FunnelFilterExpression(
+ or_group=FunnelFilterExpressionList(
+ expressions=[
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="screen_view"
+ )
+ ),
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="page_view"
+ )
+ ),
+ ]
+ )
+ ),
+ ),
+ FunnelStep(
+ name="Purchase",
+ filter_expression=FunnelFilterExpression(
+ or_group=FunnelFilterExpressionList(
+ expressions=[
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="purchase"
+ )
+ ),
+ FunnelFilterExpression(
+ funnel_event_filter=FunnelEventFilter(
+ event_name="in_app_purchase"
+ )
+ ),
+ ]
+ )
+ ),
+ ),
+ ]
+ ),
+ )
+ response = client.run_funnel_report(request)
+ print_run_funnel_report_response(response)
+
+
+# [START analyticsdata_print_run_funnel_report_response]
+def print_funnel_sub_report(funnel_sub_report):
+ """Prints the contents of a FunnelSubReport object."""
+ print("Dimension headers:")
+ for dimension_header in funnel_sub_report.dimension_headers:
+ print(dimension_header.name)
+
+ print("\nMetric headers:")
+ for metric_header in funnel_sub_report.metric_headers:
+ print(metric_header.name)
+
+ print("\nDimensions and metric values for each row in the report:")
+ for row_idx, row in enumerate(funnel_sub_report.rows):
+ print("\nRow #{}".format(row_idx))
+ for field_idx, dimension_value in enumerate(row.dimension_values):
+ dimension_name = funnel_sub_report.dimension_headers[field_idx].name
+ print("{}: '{}'".format(dimension_name, dimension_value.value))
+
+ for field_idx, metric_value in enumerate(row.metric_values):
+ metric_name = funnel_sub_report.metric_headers[field_idx].name
+ print("{}: '{}'".format(metric_name, metric_value.value))
+
+ print("\nSampling metadata for each date range:")
+ for metadata_idx, metadata in enumerate(
+ funnel_sub_report.metadata.sampling_metadatas
+ ):
+ print(
+ "Sampling metadata for date range #{}: samplesReadCount={}, "
+ "samplingSpaceSize={}".format(
+ metadata_idx, metadata.samples_read_count, metadata.sampling_space_size
+ )
+ )
+
+
+def print_run_funnel_report_response(response):
+ """Prints results of a runFunnelReport call."""
+ print("Report result:")
+ print("=== FUNNEL VISUALIZATION ===")
+ print_funnel_sub_report(response.funnel_visualization)
+
+ print("=== FUNNEL TABLE ===")
+ print_funnel_sub_report(response.funnel_table)
+
+
+# [END analyticsdata_print_run_funnel_report_response]
+
+
+# [END analyticsdata_run_funnel_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_funnel_report_test.py b/google-analytics-data/run_funnel_report_test.py
new file mode 100644
index 0000000..e8b2aaa
--- /dev/null
+++ b/google-analytics-data/run_funnel_report_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_funnel_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_funnel_report(capsys):
+ run_funnel_report.run_funnel_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_pivot_report.py b/google-analytics-data/run_pivot_report.py
new file mode 100644
index 0000000..699780c
--- /dev/null
+++ b/google-analytics-data/run_pivot_report.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation of
+a pivot report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runPivotReport
+for more information.
+"""
+# [START analyticsdata_run_pivot_report]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ OrderBy,
+ Pivot,
+ RunPivotReportRequest,
+)
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_pivot_report(property_id)
+
+
+def run_pivot_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a pivot query to build a report of session counts by country,
+ pivoted by the browser dimension."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunPivotReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[DateRange(start_date="2021-01-01", end_date="2021-01-30")],
+ pivots=[
+ Pivot(
+ field_names=["country"],
+ limit=250,
+ order_bys=[
+ OrderBy(
+ dimension=OrderBy.DimensionOrderBy(dimension_name="country")
+ )
+ ],
+ ),
+ Pivot(
+ field_names=["browser"],
+ offset=3,
+ limit=3,
+ order_bys=[
+ OrderBy(
+ metric=OrderBy.MetricOrderBy(metric_name="sessions"), desc=True
+ )
+ ],
+ ),
+ ],
+ metrics=[Metric(name="sessions")],
+ dimensions=[Dimension(name="country"), Dimension(name="browser")],
+ )
+ response = client.run_pivot_report(request)
+ print_run_pivot_report_response(response)
+
+
+def print_run_pivot_report_response(response):
+ """Prints results of a runPivotReport call."""
+ # [START analyticsdata_print_run_pivot_report_response]
+ print("Report result:")
+ for row in response.rows:
+ for dimension_value in row.dimension_values:
+ print(dimension_value.value)
+
+ for metric_value in row.metric_values:
+ print(metric_value.value)
+ # [END analyticsdata_print_run_pivot_report_response]
+
+
+# [END analyticsdata_run_pivot_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_pivot_report_test.py b/google-analytics-data/run_pivot_report_test.py
new file mode 100644
index 0000000..da010a1
--- /dev/null
+++ b/google-analytics-data/run_pivot_report_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_pivot_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_pivot_report(capsys):
+ run_pivot_report.run_pivot_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_realtime_report.py b/google-analytics-data/run_realtime_report.py
new file mode 100644
index 0000000..5efd627
--- /dev/null
+++ b/google-analytics-data/run_realtime_report.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation of
+a realtime report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runRealtimeReport
+for more information.
+"""
+# [START analyticsdata_run_realtime_report]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ Dimension,
+ Metric,
+ RunRealtimeReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_realtime_report(property_id)
+
+
+def run_realtime_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a realtime report on a Google Analytics 4 property."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunRealtimeReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="country")],
+ metrics=[Metric(name="activeUsers")],
+ )
+ response = client.run_realtime_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_realtime_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_realtime_report_test.py b/google-analytics-data/run_realtime_report_test.py
new file mode 100644
index 0000000..b0a643e
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_realtime_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_realtime_report(capsys):
+ run_realtime_report.run_realtime_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_realtime_report_with_minute_ranges.py b/google-analytics-data/run_realtime_report_with_minute_ranges.py
new file mode 100644
index 0000000..2db3772
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_minute_ranges.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Copyright 2022 Google Inc. 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 Data API sample application demonstrating the creation of
+a realtime report using minute ranges.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runRealtimeReport#body.request_body.FIELDS.minute_ranges
+for more information.
+"""
+# [START analyticsdata_run_realtime_report_with_minute_ranges]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ Metric,
+ MinuteRange,
+ RunRealtimeReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_realtime_report_with_minute_ranges(property_id)
+
+
+def run_realtime_report_with_minute_ranges(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a realtime report on a Google Analytics 4 property. Dimensions
+ field is omitted in the query, which results in total values of active users
+ returned for each minute range in the report.
+
+ Note the `dateRange` dimension added to the report response automatically
+ as a result of querying multiple minute ranges.
+ """
+ client = BetaAnalyticsDataClient()
+
+ request = RunRealtimeReportRequest(
+ property=f"properties/{property_id}",
+ metrics=[Metric(name="activeUsers")],
+ minute_ranges=[
+ MinuteRange(name="0-4 minutes ago", start_minutes_ago=4),
+ MinuteRange(
+ name="25-29 minutes ago", start_minutes_ago=29, end_minutes_ago=25
+ ),
+ ],
+ )
+ response = client.run_realtime_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_realtime_report_with_minute_ranges]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_realtime_report_with_minute_ranges_test.py b/google-analytics-data/run_realtime_report_with_minute_ranges_test.py
new file mode 100644
index 0000000..f428820
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_minute_ranges_test.py
@@ -0,0 +1,27 @@
+# Copyright 2022 Google Inc. 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 run_realtime_report_with_minute_ranges
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_metrics(capsys):
+ run_realtime_report_with_minute_ranges.run_realtime_report_with_minute_ranges(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_realtime_report_with_multiple_dimensions.py b/google-analytics-data/run_realtime_report_with_multiple_dimensions.py
new file mode 100644
index 0000000..e4c1fe0
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_multiple_dimensions.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation of
+a realtime report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
+for more information.
+"""
+# [START analyticsdata_run_realtime_report_with_multiple_dimensions]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ Dimension,
+ Metric,
+ RunRealtimeReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_realtime_report_with_multiple_dimensions(property_id)
+
+
+def run_realtime_report_with_multiple_dimensions(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a realtime report on a Google Analytics 4 property."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunRealtimeReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="country"), Dimension(name="city")],
+ metrics=[Metric(name="activeUsers")],
+ )
+ response = client.run_realtime_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_realtime_report_with_multiple_dimensions]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_realtime_report_with_multiple_dimensions_test.py b/google-analytics-data/run_realtime_report_with_multiple_dimensions_test.py
new file mode 100644
index 0000000..2f0f057
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_multiple_dimensions_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_multiple_dimensions
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_dimensions(capsys):
+ run_report_with_multiple_dimensions.run_report_with_multiple_dimensions(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_realtime_report_with_multiple_metrics.py b/google-analytics-data/run_realtime_report_with_multiple_metrics.py
new file mode 100644
index 0000000..120c326
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_multiple_metrics.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation of
+a realtime report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
+for more information.
+"""
+# [START analyticsdata_run_realtime_report_with_multiple_metrics]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ Dimension,
+ Metric,
+ RunRealtimeReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_realtime_report_with_multiple_metrics(property_id)
+
+
+def run_realtime_report_with_multiple_metrics(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a realtime report on a Google Analytics 4 property."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunRealtimeReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="unifiedScreenName")],
+ metrics=[Metric(name="screenPageViews"), Metric(name="keyEvents")],
+ )
+ response = client.run_realtime_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_realtime_report_with_multiple_metrics]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_realtime_report_with_multiple_metrics_test.py b/google-analytics-data/run_realtime_report_with_multiple_metrics_test.py
new file mode 100644
index 0000000..92ab1eb
--- /dev/null
+++ b/google-analytics-data/run_realtime_report_with_multiple_metrics_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_multiple_metrics
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_metrics(capsys):
+ run_report_with_multiple_metrics.run_report_with_multiple_metrics(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report.py b/google-analytics-data/run_report.py
new file mode 100644
index 0000000..d3c19ca
--- /dev/null
+++ b/google-analytics-data/run_report.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation
+of a basic report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
+for more information.
+"""
+# [START analyticsdata_run_report]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ MetricType,
+ RunReportRequest,
+)
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report(property_id)
+
+
+def run_report(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report of active users grouped by country."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="country")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2020-09-01", end_date="2020-09-15")],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+def print_run_report_response(response):
+ """Prints results of a runReport call."""
+ # [START analyticsdata_print_run_report_response_header]
+ print(f"{response.row_count} rows received")
+ for dimensionHeader in response.dimension_headers:
+ print(f"Dimension header name: {dimensionHeader.name}")
+ for metricHeader in response.metric_headers:
+ metric_type = MetricType(metricHeader.type_).name
+ print(f"Metric header name: {metricHeader.name} ({metric_type})")
+ # [END analyticsdata_print_run_report_response_header]
+
+ # [START analyticsdata_print_run_report_response_rows]
+ print("Report result:")
+ for rowIdx, row in enumerate(response.rows):
+ print(f"\nRow {rowIdx}")
+ for i, dimension_value in enumerate(row.dimension_values):
+ dimension_name = response.dimension_headers[i].name
+ print(f"{dimension_name}: {dimension_value.value}")
+
+ for i, metric_value in enumerate(row.metric_values):
+ metric_name = response.metric_headers[i].name
+ print(f"{metric_name}: {metric_value.value}")
+ # [END analyticsdata_print_run_report_response_rows]
+
+
+# [END analyticsdata_run_report]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_test.py b/google-analytics-data/run_report_test.py
new file mode 100644
index 0000000..d6e6f2f
--- /dev/null
+++ b/google-analytics-data/run_report_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_basic(capsys):
+ run_report.run_report(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_aggregations.py b/google-analytics-data/run_report_with_aggregations.py
new file mode 100644
index 0000000..9cee325
--- /dev/null
+++ b/google-analytics-data/run_report_with_aggregations.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+metric aggregations in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.metric_aggregations
+for more information.
+"""
+# [START analyticsdata_run_report_with_aggregations]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ MetricAggregation,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_aggregations(property_id)
+
+
+def run_report_with_aggregations(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report which includes total, maximum and minimum values for
+ each metric."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="country")],
+ metrics=[Metric(name="sessions")],
+ date_ranges=[DateRange(start_date="365daysAgo", end_date="today")],
+ metric_aggregations=[
+ MetricAggregation.TOTAL,
+ MetricAggregation.MAXIMUM,
+ MetricAggregation.MINIMUM,
+ ],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_aggregations]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_aggregations_test.py b/google-analytics-data/run_report_with_aggregations_test.py
new file mode 100644
index 0000000..420c412
--- /dev/null
+++ b/google-analytics-data/run_report_with_aggregations_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_aggregations
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_aggregations(capsys):
+ run_report_with_aggregations.run_report_with_aggregations(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_cohorts.py b/google-analytics-data/run_report_with_cohorts.py
new file mode 100644
index 0000000..38442a1
--- /dev/null
+++ b/google-analytics-data/run_report_with_cohorts.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+cohort specification in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.cohort_spec
+for more information.
+"""
+# [START analyticsdata_run_report_with_cohorts]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ Cohort,
+ CohortSpec,
+ CohortsRange,
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_cohorts(property_id)
+
+
+def run_report_with_cohorts(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report on a cohort of users whose first session happened on the
+ same week. The number of active users and user retention rate is calculated
+ for the cohort using WEEKLY granularity."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="cohort"), Dimension(name="cohortNthWeek")],
+ metrics=[
+ Metric(name="cohortActiveUsers"),
+ Metric(
+ name="cohortRetentionRate",
+ expression="cohortActiveUsers/cohortTotalUsers",
+ ),
+ ],
+ cohort_spec=CohortSpec(
+ cohorts=[
+ Cohort(
+ dimension="firstSessionDate",
+ name="cohort",
+ date_range=DateRange(
+ start_date="2021-01-03", end_date="2021-01-09"
+ ),
+ )
+ ],
+ cohorts_range=CohortsRange(
+ start_offset=0,
+ end_offset=4,
+ granularity=CohortsRange.Granularity.WEEKLY,
+ ),
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_cohorts]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_cohorts_test.py b/google-analytics-data/run_report_with_cohorts_test.py
new file mode 100644
index 0000000..06907e7
--- /dev/null
+++ b/google-analytics-data/run_report_with_cohorts_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_cohorts
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_cohorts(capsys):
+ run_report_with_cohorts.run_report_with_cohorts(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_date_ranges.py b/google-analytics-data/run_report_with_date_ranges.py
new file mode 100644
index 0000000..b228425
--- /dev/null
+++ b/google-analytics-data/run_report_with_date_ranges.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+date ranges in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.date_ranges
+for more information.
+"""
+# [START analyticsdata_run_report_with_date_ranges]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_date_ranges(property_id)
+
+
+def run_report_with_date_ranges(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using two date ranges."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[
+ DateRange(start_date="2019-08-01", end_date="2019-08-14"),
+ DateRange(start_date="2020-08-01", end_date="2020-08-14"),
+ ],
+ dimensions=[Dimension(name="platform")],
+ metrics=[Metric(name="activeUsers")],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_date_ranges]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_date_ranges_test.py b/google-analytics-data/run_report_with_date_ranges_test.py
new file mode 100644
index 0000000..552f969
--- /dev/null
+++ b/google-analytics-data/run_report_with_date_ranges_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_date_ranges
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_date_ranges(capsys):
+ run_report_with_date_ranges.run_report_with_date_ranges(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_dimension_and_metric_filters.py b/google-analytics-data/run_report_with_dimension_and_metric_filters.py
new file mode 100644
index 0000000..cc013a5
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_and_metric_filters.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+dimension and metric filters in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.dimension_filter
+for more information.
+"""
+# [START analyticsdata_run_report_with_dimension_and_metric_filters]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Filter,
+ FilterExpression,
+ FilterExpressionList,
+ Metric,
+ NumericValue,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_dimension_and_metric_filters(property_id)
+
+
+def run_report_with_dimension_and_metric_filters(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using both metric and dimension filters. A dimension filter
+ limits the report to include only users who made an in-app purchase using
+ Android platform. A metric filter specifies that only users with session
+ counts larger than 1,000 should be included."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="city")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="2020-03-31", end_date="today")],
+ metric_filter=FilterExpression(
+ filter=Filter(
+ field_name="sessions",
+ numeric_filter=Filter.NumericFilter(
+ operation=Filter.NumericFilter.Operation.GREATER_THAN,
+ value=NumericValue(int64_value=1000),
+ ),
+ )
+ ),
+ dimension_filter=FilterExpression(
+ and_group=FilterExpressionList(
+ expressions=[
+ FilterExpression(
+ filter=Filter(
+ field_name="platform",
+ string_filter=Filter.StringFilter(
+ match_type=Filter.StringFilter.MatchType.EXACT,
+ value="Android",
+ ),
+ )
+ ),
+ FilterExpression(
+ filter=Filter(
+ field_name="eventName",
+ string_filter=Filter.StringFilter(
+ match_type=Filter.StringFilter.MatchType.EXACT,
+ value="in_app_purchase",
+ ),
+ )
+ ),
+ ]
+ )
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_dimension_and_metric_filters]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_dimension_and_metric_filters_test.py b/google-analytics-data/run_report_with_dimension_and_metric_filters_test.py
new file mode 100644
index 0000000..5499574
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_and_metric_filters_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_dimension_and_metric_filters
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_dimension_and_metric_filters(capsys):
+ run_report_with_dimension_and_metric_filters.run_report_with_dimension_and_metric_filters(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_dimension_exclude_filter.py b/google-analytics-data/run_report_with_dimension_exclude_filter.py
new file mode 100644
index 0000000..532e17f
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_exclude_filter.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+dimension and metric filters in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.dimension_filter
+for more information.
+"""
+# [START analyticsdata_run_report_with_dimension_exclude_filter]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Filter,
+ FilterExpression,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_dimension_exclude_filter(property_id)
+
+
+def run_report_with_dimension_exclude_filter(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using a filter with `not_expression`. The dimension filter
+ selects for when `pageTitle` is not `My Homepage`.
+
+ This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange
+ for more information.
+ """
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="pageTitle")],
+ metrics=[Metric(name="sessions")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
+ dimension_filter=FilterExpression(
+ not_expression=FilterExpression(
+ filter=Filter(
+ field_name="pageTitle",
+ string_filter=Filter.StringFilter(value="My Homepage"),
+ )
+ )
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_dimension_exclude_filter]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_dimension_exclude_filter_test.py b/google-analytics-data/run_report_with_dimension_exclude_filter_test.py
new file mode 100644
index 0000000..3cef3fb
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_exclude_filter_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_dimension_exclude_filter
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_dimension_exclude_filter(capsys):
+ run_report_with_dimension_exclude_filter.run_report_with_dimension_exclude_filter(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_dimension_filter.py b/google-analytics-data/run_report_with_dimension_filter.py
new file mode 100644
index 0000000..64e899f
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_filter.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+dimension and metric filters in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.dimension_filter
+for more information.
+"""
+# [START analyticsdata_run_report_with_dimension_filter]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Filter,
+ FilterExpression,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_dimension_filter(property_id)
+
+
+def run_report_with_dimension_filter(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using a dimension filter. The call returns a time series
+ report of `eventCount` when `eventName` is `first_open` for each date.
+
+ This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange
+ for more information.
+ """
+
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="date")],
+ metrics=[Metric(name="eventCount")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
+ dimension_filter=FilterExpression(
+ filter=Filter(
+ field_name="eventName",
+ string_filter=Filter.StringFilter(value="first_open"),
+ )
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_dimension_filter]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_dimension_filter_test.py b/google-analytics-data/run_report_with_dimension_filter_test.py
new file mode 100644
index 0000000..b4e5791
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_filter_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_dimension_filter
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_dimension_filter(capsys):
+ run_report_with_dimension_filter.run_report_with_dimension_filter(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_dimension_in_list_filter.py b/google-analytics-data/run_report_with_dimension_in_list_filter.py
new file mode 100644
index 0000000..14c5b49
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_in_list_filter.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+dimension and metric filters in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.dimension_filter
+for more information.
+"""
+# [START analyticsdata_run_report_with_dimension_in_list_filter]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Filter,
+ FilterExpression,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_dimension_in_list_filter(property_id)
+
+
+def run_report_with_dimension_in_list_filter(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using a dimension filter with `in_list_filter` expression.
+ The filter selects for when `eventName` is set to one of three event names
+ specified in the query.
+
+ This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange
+ for more information.
+ """
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="eventName")],
+ metrics=[Metric(name="sessions")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
+ dimension_filter=FilterExpression(
+ filter=Filter(
+ field_name="eventName",
+ in_list_filter=Filter.InListFilter(
+ values=[
+ "purchase",
+ "in_app_purchase",
+ "app_store_subscription_renew",
+ ]
+ ),
+ )
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_dimension_in_list_filter]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_dimension_in_list_filter_test.py b/google-analytics-data/run_report_with_dimension_in_list_filter_test.py
new file mode 100644
index 0000000..60f34a5
--- /dev/null
+++ b/google-analytics-data/run_report_with_dimension_in_list_filter_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_dimension_in_list_filter
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_dimension_in_list_filter(capsys):
+ run_report_with_dimension_in_list_filter.run_report_with_dimension_in_list_filter(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_multiple_dimension_filters.py b/google-analytics-data/run_report_with_multiple_dimension_filters.py
new file mode 100644
index 0000000..0fe0608
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_dimension_filters.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+dimension and metric filters in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.dimension_filter
+for more information.
+"""
+# [START analyticsdata_run_report_with_multiple_dimension_filters]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Filter,
+ FilterExpression,
+ FilterExpressionList,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_multiple_dimension_filters(property_id)
+
+
+def run_report_with_multiple_dimension_filters(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using multiple dimension filters joined as `and_group`
+ expression. The filter selects for when both `browser` is `Chrome` and
+ `countryId` is `US`.
+
+ This sample uses relative date range values. See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange
+ for more information.
+ """
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="browser")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
+ dimension_filter=FilterExpression(
+ and_group=FilterExpressionList(
+ expressions=[
+ FilterExpression(
+ filter=Filter(
+ field_name="browser",
+ string_filter=Filter.StringFilter(value="Chrome"),
+ )
+ ),
+ FilterExpression(
+ filter=Filter(
+ field_name="countryId",
+ string_filter=Filter.StringFilter(value="US"),
+ )
+ ),
+ ]
+ )
+ ),
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_multiple_dimension_filters]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_multiple_dimension_filters_test.py b/google-analytics-data/run_report_with_multiple_dimension_filters_test.py
new file mode 100644
index 0000000..82f2160
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_dimension_filters_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_multiple_dimension_filters
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_dimension_filters(capsys):
+ run_report_with_multiple_dimension_filters.run_report_with_multiple_dimension_filters(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_multiple_dimensions.py b/google-analytics-data/run_report_with_multiple_dimensions.py
new file mode 100644
index 0000000..4b0e6ba
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_dimensions.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation
+of a basic report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
+for more information.
+"""
+# [START analyticsdata_run_report_with_multiple_dimensions]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_multiple_dimensions(property_id)
+
+
+def run_report_with_multiple_dimensions(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report of active users grouped by three dimensions."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[
+ Dimension(name="country"),
+ Dimension(name="region"),
+ Dimension(name="city"),
+ ],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="today")],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_multiple_dimensions]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_multiple_dimensions_test.py b/google-analytics-data/run_report_with_multiple_dimensions_test.py
new file mode 100644
index 0000000..2f0f057
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_dimensions_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_multiple_dimensions
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_dimensions(capsys):
+ run_report_with_multiple_dimensions.run_report_with_multiple_dimensions(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_multiple_metrics.py b/google-analytics-data/run_report_with_multiple_metrics.py
new file mode 100644
index 0000000..279ed40
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_metrics.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the creation
+of a basic report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport
+for more information.
+"""
+# [START analyticsdata_run_report_with_multiple_metrics]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_multiple_metrics(property_id)
+
+
+def run_report_with_multiple_metrics(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report of active users, new users and total revenue grouped by
+ date dimension."""
+ client = BetaAnalyticsDataClient()
+
+ # Runs a report of active users grouped by three dimensions.
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="date")],
+ metrics=[
+ Metric(name="activeUsers"),
+ Metric(name="newUsers"),
+ Metric(name="totalRevenue"),
+ ],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="today")],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_multiple_metrics]
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_multiple_metrics_test.py b/google-analytics-data/run_report_with_multiple_metrics_test.py
new file mode 100644
index 0000000..92ab1eb
--- /dev/null
+++ b/google-analytics-data/run_report_with_multiple_metrics_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_multiple_metrics
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_multiple_metrics(capsys):
+ run_report_with_multiple_metrics.run_report_with_multiple_metrics(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_named_date_ranges.py b/google-analytics-data/run_report_with_named_date_ranges.py
new file mode 100644
index 0000000..41aee5b
--- /dev/null
+++ b/google-analytics-data/run_report_with_named_date_ranges.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+date ranges in a report.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/DateRange#FIELDS.name
+for more information.
+"""
+# [START analyticsdata_run_report_with_named_date_ranges]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_named_date_ranges(property_id)
+
+
+def run_report_with_named_date_ranges(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report using named date ranges."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[
+ DateRange(start_date="2020-01-01", end_date="2020-01-31", name="year_ago"),
+ DateRange(
+ start_date="2021-01-01", end_date="2021-01-31", name="current_year"
+ ),
+ ],
+ dimensions=[Dimension(name="country")],
+ metrics=[Metric(name="sessions")],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_named_date_ranges]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_named_date_ranges_test.py b/google-analytics-data/run_report_with_named_date_ranges_test.py
new file mode 100644
index 0000000..0c0637f
--- /dev/null
+++ b/google-analytics-data/run_report_with_named_date_ranges_test.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Google Inc. 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 run_report_with_named_date_ranges
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_named_date_ranges(capsys):
+ run_report_with_named_date_ranges.run_report_with_named_date_ranges(
+ TEST_PROPERTY_ID
+ )
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_ordering.py b/google-analytics-data/run_report_with_ordering.py
new file mode 100644
index 0000000..fad333a
--- /dev/null
+++ b/google-analytics-data/run_report_with_ordering.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the ordering of
+ report rows.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.order_bys
+for more information.
+"""
+# [START analyticsdata_run_report_with_ordering]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ OrderBy,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_ordering(property_id)
+
+
+def run_report_with_ordering(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report of active users grouped by three dimensions, ordered by
+ the total revenue in descending order."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ dimensions=[Dimension(name="date")],
+ metrics=[
+ Metric(name="activeUsers"),
+ Metric(name="newUsers"),
+ Metric(name="totalRevenue"),
+ ],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="today")],
+ order_bys=[
+ OrderBy(metric=OrderBy.MetricOrderBy(metric_name="totalRevenue"), desc=True)
+ ],
+ )
+ response = client.run_report(request)
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_ordering]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_ordering_test.py b/google-analytics-data/run_report_with_ordering_test.py
new file mode 100644
index 0000000..28c7297
--- /dev/null
+++ b/google-analytics-data/run_report_with_ordering_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_ordering
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_ordering(capsys):
+ run_report_with_ordering.run_report_with_ordering(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_pagination.py b/google-analytics-data/run_report_with_pagination.py
new file mode 100644
index 0000000..f8af1cd
--- /dev/null
+++ b/google-analytics-data/run_report_with_pagination.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the use of
+pagination to retrieve large result sets.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.offset
+for more information.
+"""
+# [START analyticsdata_run_report_with_pagination]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+from run_report import print_run_report_response
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_pagination(property_id)
+
+
+def run_report_with_pagination(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report several times, each time retrieving a portion of result
+ using pagination."""
+ client = BetaAnalyticsDataClient()
+
+ # [START analyticsdata_run_report_with_pagination_page1]
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")],
+ dimensions=[
+ Dimension(name="firstUserSource"),
+ Dimension(name="firstUserMedium"),
+ Dimension(name="firstUserCampaignName"),
+ ],
+ metrics=[
+ Metric(name="sessions"),
+ Metric(name="keyEvents"),
+ Metric(name="totalRevenue"),
+ ],
+ limit=100000,
+ offset=0,
+ )
+ response = client.run_report(request)
+ # [END analyticsdata_run_report_with_pagination_page1]
+ print_run_report_response(response)
+
+ # Run the same report with a different offset value to retrieve the second
+ # page of a response.
+ # [START analyticsdata_run_report_with_pagination_page2]
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ date_ranges=[DateRange(start_date="365daysAgo", end_date="yesterday")],
+ dimensions=[
+ Dimension(name="firstUserSource"),
+ Dimension(name="firstUserMedium"),
+ Dimension(name="firstUserCampaignName"),
+ ],
+ metrics=[
+ Metric(name="sessions"),
+ Metric(name="keyEvents"),
+ Metric(name="totalRevenue"),
+ ],
+ limit=100000,
+ offset=100000,
+ )
+ response = client.run_report(request)
+ # [END analyticsdata_run_report_with_pagination_page2]
+ print_run_report_response(response)
+
+
+# [END analyticsdata_run_report_with_pagination]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_pagination_test.py b/google-analytics-data/run_report_with_pagination_test.py
new file mode 100644
index 0000000..b9b65e7
--- /dev/null
+++ b/google-analytics-data/run_report_with_pagination_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_pagination
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_pagination(capsys):
+ run_report_with_pagination.run_report_with_pagination(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Report result" in out
diff --git a/google-analytics-data/run_report_with_property_quota.py b/google-analytics-data/run_report_with_property_quota.py
new file mode 100644
index 0000000..cd87336
--- /dev/null
+++ b/google-analytics-data/run_report_with_property_quota.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+# Copyright 2021 Google Inc. 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 Data API sample application demonstrating the usage of
+property quota metadata.
+
+See https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport#body.request_body.FIELDS.return_property_quota
+for more information.
+"""
+# [START analyticsdata_run_report_with_property_quota]
+from google.analytics.data_v1beta import BetaAnalyticsDataClient
+from google.analytics.data_v1beta.types import (
+ DateRange,
+ Dimension,
+ Metric,
+ RunReportRequest,
+)
+
+
+def run_sample():
+ """Runs the sample."""
+ # TODO(developer): Replace this variable with your Google Analytics 4
+ # property ID before running the sample.
+ property_id = "YOUR-GA4-PROPERTY-ID"
+ run_report_with_property_quota(property_id)
+
+
+def run_report_with_property_quota(property_id="YOUR-GA4-PROPERTY-ID"):
+ """Runs a report and prints property quota information."""
+ client = BetaAnalyticsDataClient()
+
+ request = RunReportRequest(
+ property=f"properties/{property_id}",
+ return_property_quota=True,
+ dimensions=[Dimension(name="country")],
+ metrics=[Metric(name="activeUsers")],
+ date_ranges=[DateRange(start_date="7daysAgo", end_date="today")],
+ )
+ response = client.run_report(request)
+
+ # [START analyticsdata_run_report_with_property_quota_print_response]
+ if response.property_quota:
+ print(
+ f"Tokens per day quota consumed: {response.property_quota.tokens_per_day.consumed}, "
+ f"remaining: {response.property_quota.tokens_per_day.remaining}."
+ )
+
+ print(
+ f"Tokens per hour quota consumed: {response.property_quota.tokens_per_hour.consumed}, "
+ f"remaining: {response.property_quota.tokens_per_hour.remaining}."
+ )
+
+ print(
+ f"Concurrent requests quota consumed: {response.property_quota.concurrent_requests.consumed}, "
+ f"remaining: {response.property_quota.concurrent_requests.remaining}."
+ )
+
+ print(
+ f"Server errors per project per hour quota consumed: {response.property_quota.server_errors_per_project_per_hour.consumed}, "
+ f"remaining: {response.property_quota.server_errors_per_project_per_hour.remaining}."
+ )
+ print(
+ f"Potentially thresholded requests per hour quota consumed: {response.property_quota.potentially_thresholded_requests_per_hour.consumed}, "
+ f"remaining: {response.property_quota.potentially_thresholded_requests_per_hour.remaining}."
+ )
+ # [END analyticsdata_run_report_with_property_quota_print_response]
+
+
+# [END analyticsdata_run_report_with_property_quota]
+
+
+if __name__ == "__main__":
+ run_sample()
diff --git a/google-analytics-data/run_report_with_property_quota_test.py b/google-analytics-data/run_report_with_property_quota_test.py
new file mode 100644
index 0000000..1b17fb8
--- /dev/null
+++ b/google-analytics-data/run_report_with_property_quota_test.py
@@ -0,0 +1,25 @@
+# Copyright 2021 Google Inc. 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 run_report_with_property_quota
+
+TEST_PROPERTY_ID = os.getenv("GA_TEST_PROPERTY_ID")
+
+
+def test_run_report_with_property_quota(capsys):
+ run_report_with_property_quota.run_report_with_property_quota(TEST_PROPERTY_ID)
+ out, _ = capsys.readouterr()
+ assert "Tokens per day quota consumed" in out