Skip to content

Commit

Permalink
Asyncio sample (#11837)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorbernstein2 authored Jun 10, 2024
1 parent 5b6e3d9 commit 8cf862f
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
64 changes: 64 additions & 0 deletions functions/bigtable/main_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2024 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.

# [START bigtable_functions_quickstart_asyncio]
import asyncio

import functions_framework
from google.cloud.bigtable.data import BigtableDataClientAsync, ReadRowsQuery, RowRange

event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(event_loop)


# Setup: create a shared client within the context of the event loop
async def create_client():
# create client in the asyncio event loop context to
# give background tasks a chance to initialize
return BigtableDataClientAsync()


client = event_loop.run_until_complete(create_client())


# Actual cloud functions entrypoint, will delegate to the async one
@functions_framework.http
def bigtable_read_data(request):
return event_loop.run_until_complete(_bigtable_read_data_async(request))


# Actual handler
async def _bigtable_read_data_async(request):
async with client.get_table(
request.headers.get("instance_id"), request.headers.get("table_id")
) as table:

prefix = "phone#"
end_key = prefix[:-1] + chr(ord(prefix[-1]) + 1)

outputs = []
query = ReadRowsQuery(row_ranges=[RowRange(start_key=prefix, end_key=end_key)])

async for row in await table.read_rows_stream(query):
print("%s" % row)
output = "Rowkey: {}, os_build: {}".format(
row.row_key.decode("utf-8"),
row.get_cells("stats_summary", b"os_build")[0].value.decode("utf-8"),
)
outputs.append(output)

return "\n".join(outputs)


# [END bigtable_functions_quickstart_asyncio]
69 changes: 69 additions & 0 deletions functions/bigtable/main_async_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2024 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.

import datetime
import os
import uuid

from google.cloud import bigtable
import pytest
from requests import Request

import main_async

PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
BIGTABLE_INSTANCE = os.environ["BIGTABLE_INSTANCE"]
TABLE_ID_PREFIX = "mobile-time-series-{}"


@pytest.fixture(scope="module", autouse=True)
def table_id():
client = bigtable.Client(project=PROJECT, admin=True)
instance = client.instance(BIGTABLE_INSTANCE)

table_id = TABLE_ID_PREFIX.format(str(uuid.uuid4())[:16])
table = instance.table(table_id)
if table.exists():
table.delete()

table.create(column_families={"stats_summary": None})

timestamp = datetime.datetime(2019, 5, 1)
rows = [
table.direct_row("phone#4c410523#20190501"),
table.direct_row("phone#4c410523#20190502"),
]

rows[0].set_cell("stats_summary", "os_build", "PQ2A.190405.003", timestamp)
rows[1].set_cell("stats_summary", "os_build", "PQ2A.190405.004", timestamp)

table.mutate_rows(rows)

yield table_id

table.delete()


def test_main(table_id):
request = Request(
"GET", headers={"instance_id": BIGTABLE_INSTANCE, "table_id": table_id}
)

response = main_async.bigtable_read_data(request)

assert (
"""Rowkey: phone#4c410523#20190501, os_build: PQ2A.190405.003
Rowkey: phone#4c410523#20190502, os_build: PQ2A.190405.004"""
in response
)
3 changes: 2 additions & 1 deletion functions/bigtable/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
google-cloud-bigtable==2.19.0
functions-framework==3.7.0
google-cloud-bigtable==2.23.1

0 comments on commit 8cf862f

Please sign in to comment.