diff --git a/.github/renovate.json5 b/.github/renovate.json5
new file mode 100644
index 0000000..bc74ad7
--- /dev/null
+++ b/.github/renovate.json5
@@ -0,0 +1,27 @@
+// 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
+    },
+}
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 <https://cla.developers.google.com/> 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..7832fa2
--- /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"]
+
+# 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..93cd38b
--- /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"],
+    # 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..225ee3d
--- /dev/null
+++ b/google-analytics-admin/requirements-test.txt
@@ -0,0 +1 @@
+pytest==8.4.1
\ 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..75035a8
--- /dev/null
+++ b/google-analytics-admin/requirements.txt
@@ -0,0 +1,2 @@
+google-analytics-admin==0.24.1
+google-auth-oauthlib==1.2.2
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/noxfile.py b/google-analytics-data/noxfile.py
new file mode 100644
index 0000000..7832fa2
--- /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"]
+
+# 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..ffae361
--- /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"],
+    # 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..8e0e884
--- /dev/null
+++ b/google-analytics-data/requirements-test.txt
@@ -0,0 +1 @@
+pytest==8.4.1
diff --git a/google-analytics-data/requirements.txt b/google-analytics-data/requirements.txt
new file mode 100644
index 0000000..a9c0137
--- /dev/null
+++ b/google-analytics-data/requirements.txt
@@ -0,0 +1,2 @@
+google-analytics-data==0.18.19
+google-auth-oauthlib==1.2.2
\ 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
