# Python hello world

This example is a "hello world" application, written in Python, that
illustrates how to do the following:

- Set up authentication.
- Connect to a Bigtable instance.
- Create a new table.
- Write data to the table.
- Read the data back.
- Delete the table.


The Python client library for Bigtable offers two APIs, `asyncio`
and a synchronous API. If your application is asynchronous, use `asyncio`.

## Set up authentication


To use the Python samples on this page in a local development environment, install and
initialize the gcloud CLI, and then set up Application Default Credentials with
your user credentials.

1.
   [Install](https://docs.cloud.google.com/sdk/docs/install) the Google Cloud CLI.

2. If you're using an external identity provider (IdP), you must first
   [sign in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).

3.

   If you're using a local shell, then create local authentication credentials for your user
   account:

   ```bash
   gcloud auth application-default login
   ```

   You don't need to do this if you're using Cloud Shell.


   If an authentication error is returned, and you are using an external identity provider
   (IdP), confirm that you have
   [signed in to the gcloud CLI with your federated identity](https://docs.cloud.google.com/iam/docs/workforce-log-in-gcloud).


For more information, see
[Set up authentication for a local development environment](https://docs.cloud.google.com/bigtable/docs/authentication#local-development).

## Run the sample

This example uses the [Bigtable package](https://docs.cloud.google.com/python/docs/reference/bigtable/latest)
of the [Cloud Client Libraries for Python](https://docs.cloud.google.com/python/docs/reference) to communicate
with Bigtable. The Bigtable package is the best
choice for new applications. If you need to move an existing HBase workload to
Bigtable, see the ["hello world" example that uses the HappyBase
package](https://docs.cloud.google.com/bigtable/docs/samples-python-hello-happybase).

To run this sample program, follow the [instructions for the sample on
GitHub](https://github.com/googleapis/python-bigtable/tree/master/samples/hello).

## Use the Cloud Client Libraries with Bigtable

The sample application connects to Bigtable and demonstrates some
operations.

### Install and import the client library

Use [PIP](https://pip.pypa.io/en/stable/) to install the required Python packages into a
[virtualenv environment](https://virtualenv.pypa.io/en/stable/). The sample includes a [requirements
file](https://pip.pypa.io/en/stable/user_guide/#requirements-files) defining the needed packages.

    google-cloud-bigtable==2.35.0
    google-cloud-core==2.5.0

Import the modules.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    from google.cloud import https://docs.cloud.google.com/python/docs/reference/bigtable/latest
    from google.cloud.bigtable.data import row_filters

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    from datetime import datetime, timezone

    from google.cloud import https://docs.cloud.google.com/python/docs/reference/bigtable/latest
    from google.cloud.bigtable import column_family
    from google.cloud.bigtable import row_filters

### Connect to Bigtable

Connect to Bigtable using a
[`bigtable.Client`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest).

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    client = bigtable.data.BigtableDataClientAsync(project=project_id)
    table = client.get_table(instance_id, table_id)

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    # The client must be created with admin=True because it will create a
    # table.
    client = bigtable.Client(project=project_id, admin=True)
    instance = client.instance(instance_id)

### Create a table

Instantiate a table object using [`Instance.table()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.instance.Instance#google_cloud_bigtable_instance_Instance_table). Create a column family and set its
garbage collection policy, then pass the column family to [`Table.create()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_create) to create the table.

> [!NOTE]
> **Note:** Columns that are related to one another are typically grouped into a column family. For more information about column families, see the [Bigtable
> storage model](https://docs.cloud.google.com/bigtable/docs/overview#storage-model). The async client only supports Data API. Table creation is an admin operation and uses the regular admin client.

    print("Creating the {} table.".format(table_id))
    table = instance.table(table_id)

    print("Creating column family cf1 with Max Version GC rule...")
    # Create a column family with GC policy : most recent N versions
    # Define the GC policy to retain only the most recent 2 versions
    max_versions_rule = bigtable.column_family.MaxVersionsGCRule(2)
    column_family_id = b"cf1"
    column_families = {column_family_id: max_versions_rule}
    if not table.exists():
        table.create(column_families=column_families)
    else:
        print("Table {} already exists.".format(table_id))

### Write rows to a table

Loop through a list of greeting strings to create some new rows for the table.
In each iteration, use [`Table.row()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_row) to define a row
and assign it a row key; call [`Row.set_cell()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row.ConditionalRow#google_cloud_bigtable_row_ConditionalRow_set_cell) to
set a value for the current cell; and append the new row to an array of rows.
Finally, call [`Table.mutate_rows()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_mutate_rows) to add
the rows to the table.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Writing some greetings to the table.")
    greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"]
    mutations = []
    column = b"greeting"
    for i, value in enumerate(greetings):
        # Note: This example uses sequential numeric IDs for simplicity,
        # but this can result in poor performance in a production
        # application.  Since rows are stored in sorted order by key,
        # sequential keys can result in poor distribution of operations
        # across nodes.
        #
        # We recommend that you use bytestrings directly for row keys
        # where possible, rather than encoding strings.
        #
        # For more information about how to design a Bigtable schema for
        # the best performance, see the documentation:
        #
        #     https://cloud.google.com/bigtable/docs/schema-design
        row_key = f"greeting{i}".encode()
        row_mutation = bigtable.data.RowMutationEntry(
            row_key, bigtable.data.SetCell(column_family_id, column, value)
        )
        mutations.append(row_mutation)
    await table.bulk_mutate_rows(mutations)

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Writing some greetings to the table.")
    greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"]
    rows = []
    column = b"greeting"
    for i, value in enumerate(greetings):
        # Note: This example uses sequential numeric IDs for simplicity,
        # but this can result in poor performance in a production
        # application.  Since rows are stored in sorted order by key,
        # sequential keys can result in poor distribution of operations
        # across nodes.
        #
        # We recommend that you use bytestrings directly for row keys
        # where possible, rather than encoding strings.
        #
        # For more information about how to design a Bigtable schema for
        # the best performance, see the documentation:
        #
        #     https://cloud.google.com/bigtable/docs/schema-design
        row_key = f"greeting{i}".encode()
        row = table.direct_row(row_key)
        row.set_cell(
            column_family_id, column, value, timestamp=datetime.now(timezone.utc),
        )
        rows.append(row)
    table.mutate_rows(rows)

### Create a filter

Before you read the data that you wrote, create a filter using [`row_filters.CellsColumnLimitFilter()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row_filters.CellsColumnLimitFilter) to limit the data that
Bigtable returns. This filter tells Bigtable to
return only the most recent cell in each column, even if the table contains
older cells that haven't been removed yet during garbage collection.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    # Create a filter to only retrieve the most recent version of the cell
    # for each column across entire row.
    row_filter = bigtable.data.row_filters.CellsColumnLimitFilter(1)

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    row_filter = bigtable.row_filters.CellsColumnLimitFilter(1)

### Read a row by its row key

Call the table's [`Table.read_row()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_read_row) method to get a reference to
the row with a specific row key, passing in the key and the filter, to get one
version of each value in that row.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Getting a single greeting by row key.")
    key = "greeting0".encode()

    row = await table.read_row(key, row_filter=row_filter)
    cell = row.cells[0]
    print(cell.value.decode("utf-8"))

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Getting a single greeting by row key.")
    key = b"greeting0"

    row = table.read_row(key, row_filter)
    cell = row.cells[column_family_id.decode("utf-8")][column][0]
    print(cell.value.decode("utf-8"))

### Scan all table rows

Use [`Table.read_rows()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_read_rows) to read a range of rows
from a table.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Scanning for all greetings:")
    query = bigtable.data.ReadRowsQuery(row_filter=row_filter)
    async for row in await table.read_rows_stream(query):
        cell = row.cells[0]
        print(cell.value.decode("utf-8"))

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).

    print("Scanning for all greetings:")
    partial_rows = table.read_rows(filter_=row_filter)

    for row in partial_rows:
        column_family_id_str = column_family_id.decode("utf-8")
        cell = row.cells[column_family_id_str][column][0]
        print(cell.value.decode("utf-8"))

### Delete a table

Delete a table with [`Table.delete()`](https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table#google_cloud_bigtable_table_Table_delete).

> [!NOTE]
> **Note:** The async client only supports the Data API. Table creation is an admin operation and uses the regular admin client.

    print("Deleting the {} table.".format(table_id))
    table.delete()

## Put it all together

Here is the full example without comments.

### Asyncio


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).



    """Demonstrates how to connect to Cloud Bigtable and run some basic operations with the async APIs

    Prerequisites:

    - Create a Cloud Bigtable instance.
      https://cloud.google.com/bigtable/docs/creating-instance
    - Set your Google Application Default Credentials.
      https://developers.google.com/identity/protocols/application-default-credentials
    """

    import argparse
    import asyncio
    from ..utils import wait_for_table

    from google.cloud import https://docs.cloud.google.com/python/docs/reference/bigtable/latest
    from google.cloud.bigtable.data import row_filters

    row_filters


    async def main(project_id, instance_id, table_id):
        client = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.data.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.BigtableDataClientAsync.html(project=project_id)
        table = https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.html.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.BigtableDataClientAsync.html#google_cloud_bigtable_data_BigtableDataClientAsync_get_table(instance_id, table_id)

        from google.cloud.bigtable import column_family

        print("Creating the {} table.".format(table_id))
        admin_client = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.Client.html(project=project_id, admin=True)
        admin_instance = admin_client.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.Client.html#google_cloud_bigtable_client_Client_instance(instance_id)
        admin_table = admin_instance.table(table_id)

        print("Creating column family cf1 with Max Version GC rule...")
        max_versions_rule = column_family.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.column_family.MaxVersionsGCRule.html(2)
        column_family_id = b"cf1"
        column_families = {column_family_id: max_versions_rule}
        if not admin_table.exists():
            admin_table.create(column_families=column_families)
        else:
            print("Table {} already exists.".format(table_id))

        try:
            wait_for_table(admin_table)
            print("Writing some greetings to the table.")
            greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"]
            mutations = []
            column = b"greeting"
            for i, value in enumerate(greetings):
                row_key = f"greeting{i}".encode()
                row_mutation = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.data.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.mutations.RowMutationEntry.html(
                    row_key, https://docs.cloud.google.com/python/docs/reference/bigtable/latest.data.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.mutations.SetCell.html(column_family_id, column, value)
                )
                https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.mutations.html.append(row_mutation)
            await table.bulk_mutate_rows(mutations)

            row_filter = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.data.row_filters.CellsColumnLimitFilter(1)

            print("Getting a single greeting by row key.")
            key = "greeting0".encode()

            row = await table.read_row(key, row_filter=row_filter)
            cell = row.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row.PartialRowData.html#google_cloud_bigtable_row_PartialRowData_cells[0]
            print(cell.value.decode("utf-8"))

            print("Scanning for all greetings:")
            query = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.data.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.data.read_rows_query.ReadRowsQuery.html(row_filter=row_filter)
            async for row in await table.read_rows_stream(query):
                cell = row.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row.PartialRowData.html#google_cloud_bigtable_row_PartialRowData_cells[0]
                print(cell.value.decode("utf-8"))
        finally:
            print("Deleting the {} table.".format(table_id))
            admin_table.delete()


    if __name__ == "__main__":
        parser = argparse.ArgumentParser(
            description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter
        )
        parser.add_argument("project_id", help="Your Cloud Platform project ID.")
        parser.add_argument(
            "instance_id", help="ID of the Cloud Bigtable instance to connect to."
        )
        parser.add_argument(
            "--table", help="Table to create and destroy.", default="Hello-Bigtable"
        )

        args = parser.parse_args()
        asyncio.run(main(args.project_id, args.instance_id, args.table))

### Sync


To learn how to install and use the client library for Bigtable, see
[Bigtable client libraries](https://docs.cloud.google.com/bigtable/docs/reference/libraries).


To authenticate to Bigtable, set up Application Default Credentials.
For more information, see

[Set up authentication for client libraries](https://docs.cloud.google.com/bigtable/docs/authentication#client-libs).



    """Demonstrates how to connect to Cloud Bigtable and run some basic operations.

    Prerequisites:

    - Create a Cloud Bigtable instance.
      https://cloud.google.com/bigtable/docs/creating-instance
    - Set your Google Application Default Credentials.
      https://developers.google.com/identity/protocols/application-default-credentials
    """

    import argparse
    from ..utils import wait_for_table

    from datetime import datetime, timezone

    from google.cloud import https://docs.cloud.google.com/python/docs/reference/bigtable/latest
    from google.cloud.bigtable import column_family
    from google.cloud.bigtable import row_filters


    row_filters
    column_family


    def main(project_id, instance_id, table_id):
        client = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.Client.html(project=project_id, admin=True)
        instance = https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.html.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.client.Client.html#google_cloud_bigtable_client_Client_instance(instance_id)

        print("Creating the {} table.".format(table_id))
        table = instance.table(table_id)

        print("Creating column family cf1 with Max Version GC rule...")
        max_versions_rule = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.column_family.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.column_family.MaxVersionsGCRule.html(2)
        column_family_id = b"cf1"
        column_families = {column_family_id: max_versions_rule}
        if not table.exists():
            table.create(column_families=column_families)
        else:
            print("Table {} already exists.".format(table_id))

        try:
            wait_for_table(table)

            print("Writing some greetings to the table.")
            greetings = [b"Hello World!", b"Hello Cloud Bigtable!", b"Hello Python!"]
            rows = []
            column = b"greeting"
            for i, value in enumerate(greetings):
                row_key = f"greeting{i}".encode()
                row = table.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.table.Table.html#google_cloud_bigtable_table_Table_direct_row(row_key)
                row.set_cell(
                    column_family_id, column, value, timestamp=datetime.now(timezone.utc),
                )
                rows.append(row)
            table.mutate_rows(rows)

            row_filter = https://docs.cloud.google.com/python/docs/reference/bigtable/latest.row_filters.CellsColumnLimitFilter(1)

            print("Getting a single greeting by row key.")
            key = b"greeting0"

            row = table.read_row(key, row_filter)
            cell = row.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row.PartialRowData.html#google_cloud_bigtable_row_PartialRowData_cells[column_family_id.decode("utf-8")][column][0]
            print(cell.value.decode("utf-8"))

            print("Scanning for all greetings:")
            partial_rows = table.read_rows(filter_=row_filter)

            for row in partial_rows:
                column_family_id_str = column_family_id.decode("utf-8")
                cell = row.https://docs.cloud.google.com/python/docs/reference/bigtable/latest/google.cloud.bigtable.row.PartialRowData.html#google_cloud_bigtable_row_PartialRowData_cells[column_family_id_str][column][0]
                print(cell.value.decode("utf-8"))

        finally:
            print("Deleting the {} table.".format(table_id))
            table.delete()


    if __name__ == "__main__":
        parser = argparse.ArgumentParser(
            description=__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter
        )
        parser.add_argument("project_id", help="Your Cloud Platform project ID.")
        parser.add_argument(
            "instance_id", help="ID of the Cloud Bigtable instance to connect to."
        )
        parser.add_argument(
            "--table", help="Table to create and destroy.", default="Hello-Bigtable"
        )

        args = parser.parse_args()
        main(args.project_id, args.instance_id, args.table)