Make your first API call using gRPC

1. Introduction

The Google Health API supports gRPC for high-performance and low-latency data retrieval. Unlike REST, using gRPC requires obtaining the API's Protocol Buffers (protobuf) definitions and generating client-side stub code before making requests.

In this codelab, you will learn how to set up a Python development environment, retrieve the public API proto definitions, compile them using protocol buffers compiler libraries, and make your first gRPC call to retrieve health data.

What you'll learn

  • How to set up a client ID within the Google Cloud console.
  • How to set up a Python virtual environment and install gRPC dependencies.
  • How to obtain the Google Health API Protocol Buffers definitions.
  • How to compile proto files to generate client code.
  • How to go through Google OAuth 2.0 authorization flow to get an access token and refresh token.
  • How to make gRPC calls to Google Health API endpoints using Python.

What you'll need

  • Google Health mobile app
  • Python 3.8+ installed on your system
  • VS Code or another text editor and terminal of your choice

To set up the Google Health mobile app:

  1. In either the Apple App Store or the Google Play Store, search for the Google Health mobile app and download it.
  2. Select the app icon.
  3. Click Sign in with Google
  4. Select your Google Account and press the Continue button.

2. Setup Google Cloud project

You will use the Google Cloud console to create a client ID and enable use of the Google Health API.

  1. Sign in into the Google Cloud console.
  2. To create a new project:
    1. Click Select a project from the project picker.
    2. In the upper right corner, select New Project.
    3. Enter your Project name.
    4. Enter your Location (for example, "No organization").
    5. Click the Create button.
    6. Select your project.

Enable the Google Health API

  1. In the upper lefthand corner, click the menu icon:menu
  2. Select APIs & Services > Library.
  3. Search for "Google Health API" and enable it.

Setup your OAuth credentials

If you are not in the Google Cloud console, go to Google Cloud console.

  1. In the upper lefthand corner, click the menu icon:menu
  2. Select APIs & Services > Credentials.
  3. At the top center, select + Create Credentials > OAuth client ID.
  4. Click the Configure consent screen button. If the message "Google Auth Platform not configured yet" appears, click the Get Started button.
  5. In section 1:
    1. Enter the App name.
    2. Enter the User support email.
    3. Click the Next button.
  6. In section 2:
    1. Select External.
    2. Click the Next button.
  7. In section 3:
    1. Enter your email address in the Contact Information field.
    2. Click the Next button.
  8. In section 4:
    1. Click the checkbox to agree to Google's API Services User Data Policy.
    2. Click the Create button.
  9. Navigate back to APIs & Services > Credentials and select + Create Credentials > OAuth client ID.
  10. Choose the application type Desktop Application.
  11. Enter the client ID Name (for example, "Google Health API gRPC Codelab").
  12. Click the Create button.
  13. The Google Console will show a message that your client ID is created. Click the Download JSON link to download the client ID and client secret file. Since the browser will download it with a default name that includes your client ID (such as client_secret_.json), you must rename this file to client_secret.json. We will place this file in our codebase later.
  14. Click OK. You will return to the "OAuth 2.0 Client IDs" page.

Add test users

  1. On the left pane, select Audience. You should see the Publishing status set to Testing, and the User type set to External.
  2. Under the Test users section, click the + Add users button. Enter the email address for the Google Account you signed in with on your Google Health mobile app.
  3. Click the Save button.

Add scopes to the client ID

  1. On the left pane, select Data Access.
  2. Click the button Add or remove scopes.
  3. In the API column, search for "Google Health API". For this codelab we are using the scope https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  4. After selecting the scope, press the Update button to return to the Data Access page.
  5. Click the Save button.

You have finished setting up your client ID.

3. Add data to the Google Health mobile app

For new users to the Google Health API, you might not have data in your Google Health account to query. We're going to manually add an exercise log which we can query through one of the endpoints. To manually record an exercise, follow these steps:

  1. Open the Google Health mobile app on your device. Sign into your Google Health account if needed.
  2. In the bottom right-hand corner of the screen, tap the + button.
  3. In the Manually log section, tap Activity.
  4. Search for the exercise type Walk and select it.
  5. Enter a Start time for today.
  6. Change the Duration to 15 minutes.
  7. Leave the Distance as 1.0 mi.
  8. Tap Add.
  9. Sync the mobile app to the Google Health servers by long pressing on the screen and sliding it down. When you release your finger, you should see the mobile app sync.
  10. In the Activity section, you should see your manually logged Walk entry.Activity list

4. Set up Python project and dependencies

We will set up a local workspace directory and establish a Python virtual environment to manage dependencies for this codelab.

  1. Open your terminal.
  2. Run the setup command for your operating system:
    • On macOS/Linux:
      mkdir health-grpc-codelab && cd health-grpc-codelab && python3 -m venv venv && source venv/bin/activate && pip install grpcio grpcio-tools google-auth google-auth-oauthlib googleapis-common-protos
      
    • On Windows (Command Prompt):
      mkdir health-grpc-codelab && cd health-grpc-codelab && python3 -m venv venv && venv\Scripts\activate.bat && pip install grpcio grpcio-tools google-auth google-auth-oauthlib googleapis-common-protos
      
    • On Windows (PowerShell):
      mkdir health-grpc-codelab; cd health-grpc-codelab; python3 -m venv venv; venv\Scripts\Activate.ps1; pip install grpcio grpcio-tools google-auth google-auth-oauthlib googleapis-common-protos
      
    • grpcio: The core gRPC library.
    • grpcio-tools: The protobuf compiler toolchain for Python.
    • google-auth / google-auth-oauthlib: Safe mechanisms to handle credentials and OAuth authorization.
    • googleapis-common-protos: Package containing the helper modules (like google.api.annotations_pb2) imported by the generated stub files.
  3. Move the renamed client_secret.json credentials file you downloaded in the previous section into this parent health-grpc-codelab folder.

5. Obtain protos and generate stubs

Before requesting data over gRPC, we must compile the protocol buffer (.proto) definitions matching the Google Health API into client stubs.

Because the schemas depend on various shared Google API files (such as annotations, operations, and field behaviors), the easiest way is to clone the official, public Google APIs repository.

  1. Clone the googleapis GitHub repository, compile the required client schemas, and return to your parent workspace folder in one step:
    git clone --depth 1 https://github.com/googleapis/googleapis.git && \
    cd googleapis && \
    python3 -m grpc_tools.protoc \
      --proto_path=. \
      --python_out=. \
      --grpc_python_out=. \
      google/devicesandservices/health/v4/data_points.proto \
      google/devicesandservices/health/v4/data_model.proto \
      google/devicesandservices/health/v4/data_source.proto \
      google/devicesandservices/health/v4/data_coordinates.proto \
      google/devicesandservices/health/v4/medical_device_info.proto && \
    cd ..
    
    This will compile the protobufs and generate .py stub files directly in the googleapis/google/devicesandservices/health/v4/ subdirectory.

6. Implement gRPC client code in Python

To authenticate and request data, we will write a script.

  1. Create a file named client.py in the root of the health-grpc-codelab directory.
  2. Populate client.py with the following code:
import sys
# Add the 'googleapis' directory to sys.path so files in it can be imported
sys.path.insert(0, 'googleapis')

import os
import json
import grpc

import google.auth
from google.auth.transport.grpc import secure_authorized_channel
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow

# Import compiled gRPC stubs & message modules
from google.devicesandservices.health.v4 import data_points_pb2
from google.devicesandservices.health.v4 import data_points_pb2_grpc
from google.devicesandservices.health.v4 import data_source_pb2
from google.devicesandservices.health.v4 import data_model_pb2

# --- CONFIGURATION ---
CLIENT_SECRETS_FILE = 'client_secret.json'
SCOPES = ['https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly']
TOKEN_FILE = 'token.json'
GRPC_ENDPOINT = 'health.googleapis.com'

def get_credentials():
    """Gets or creates OAuth 2.0 credentials."""
    creds = None
    # Load token from disk if it was already authorized
    if os.path.exists(TOKEN_FILE):
        with open(TOKEN_FILE, 'r') as token:
            creds = Credentials.from_authorized_user_info(json.load(token), SCOPES)
    # Refresh token if expired
    if creds and creds.expired and creds.refresh_token:
        try:
            creds.refresh(Request())
        except Exception as e:
            creds = None  # Force re-authentication if refresh fails
    # Run user consent flow if not authorized yet
    if not creds or not creds.valid:
        flow = InstalledAppFlow.from_client_secrets_file(
            CLIENT_SECRETS_FILE, SCOPES
        )
        # Using desktop app loopback mechanism (opens local browser)
        creds = flow.run_local_server(port=0)
        with open(TOKEN_FILE, 'w') as token:
            token.write(creds.to_json())
    return creds

def fetch_health_data_grpc(creds):
    """Fetches health data using gRPC."""
    try:
        # 1. Establish secure, authorized channel using OAuth 2.0 Credentials
        channel = secure_authorized_channel(creds, Request(), f'{GRPC_ENDPOINT}:443')

        # 2. Instantiate the service stub client
        stub = data_points_pb2_grpc.DataPointsServiceStub(channel)

        # 3. Request data points for data type "exercise"
        print("Sending ListDataPoints RPC...")
        request = data_points_pb2.ListDataPointsRequest(parent='users/me/dataTypes/exercise')
        response = stub.ListDataPoints(request)

        # 4. Display result
        print('--- Success ---')
        for dp in response.data_points:
            platform_str = data_source_pb2.DataSource.Platform.Name(dp.data_source.platform)
            exercise_str = data_model_pb2.Exercise.ExerciseType.Name(dp.exercise.exercise_type)

            print(f"Data Point ID: {dp.name}")
            print(f"Platform: {platform_str}")
            print(f"Exercise type: {exercise_str}")
            print(f"Display Name: {dp.exercise.display_name}")
            print(f"Start Time: {dp.exercise.interval.start_time.ToJsonString()}")
            print(f"Calories (kcal): {int(dp.exercise.metrics_summary.calories_kcal)}")
            print(f"Steps: {dp.exercise.metrics_summary.steps}")
            print('----------------')
    except grpc.RpcError as e:
        print(f'gRPC Error: {e.code()} - {e.details()}')
    except Exception as e:
        print(f'General error: {e}')

if __name__ == '__main__':
    try:
        print("Retrieving OAuth 2.0 credentials...")
        creds = get_credentials()
        print("Making gRPC requests...")
        fetch_health_data_grpc(creds)
    except Exception as e:
        print(f"An error occurred: {e}")

Code explanation

Here is a breakdown of how the client script uses gRPC to interact with the Google Health API:

  • Importing Generated Stubs (Lines 243–261): First, the script adds the directory containing the compiled protobuf schemas (googleapis/) to the system import path. It then imports the generated Python modules:
    • data_points_pb2_grpc: Contains the client stub (DataPointsServiceStub) representing the API service.
    • data_points_pb2 & other _pb2 modules: Contain the message classes (like ListDataPointsRequest) and data schemas utilized by the request and response.
  • Establishing a Secure Channel (Lines 296–297):
    channel = secure_authorized_channel(creds, Request(), f'{GRPC_ENDPOINT}:443')
    
    In gRPC, a channel represents a connection to the remote endpoint. This code uses secure_authorized_channel from the google-auth library to establish a secure TLS connection on port 443 that automatically appends OAuth 2.0 authorization credentials to all call metadata.
  • Instantiating the Client Stub (Line 300):
    stub = data_points_pb2_grpc.DataPointsServiceStub(channel)
    
    This instantiates a local client stub (or client class) representing the Health API's DataPointsService service definitions. You invoke all remote procedures directly through this stub.
  • Executing the RPC Call (Lines 304–305):
    request = data_points_pb2.ListDataPointsRequest(parent='users/me/dataTypes/exercise')
    response = stub.ListDataPoints(request)
    
    You construct a strongly-typed ListDataPointsRequest specifying the target user and data type path. You then call the ListDataPoints RPC on your stub, passing the request object. The gRPC library serializes the message to binary, transmits it over HTTP/2, and returns a strongly-typed response message.
  • Accessing Data & Enum Mapping (Lines 309–319): Protobuf messages utilize efficient types. For enum values, you use generated descriptor helpers (like DataSource.Platform.Name() and Exercise.ExerciseType.Name()) to convert raw numeric enum values returned by the API into user-friendly names (For example, WALKING or FITBIT).

7. Run the script and verify responses

Execute the client script and authorize access.

  1. In your terminal (still in active virtual environment, in the root health-grpc-codelab directory), run:
    python3 client.py
    
  2. The script will output:
    Retrieving OAuth 2.0 credentials...
    Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/v2/auth...
    
    Your web browser should automatically open the consent screen.
  3. Sign in using the test user email address registered to your Google Cloud Console project.
  4. On the consent screen, click Continue to approve permissions.
  5. Upon success, you will see the browser show The authentication flow has completed. You may close this window.
  6. Return to your terminal. The script will print the exercise data we manually logged on the mobile app:
    Making gRPC requests...
    Sending ListDataPoints RPC...
    --- Success ---
    Data Point ID: users/123456789/dataTypes/exercise/dataPoints/8896720705097069096
    Platform: FITBIT
    Exercise type: WALKING
    Display Name: Walk
    Start Time: 2026-02-23T13:10:00Z
    Calories (kcal): 16
    Steps: 2038
    ----------------
    

8. Fetch a different data type

To retrieve data for a different type (such as daily steps), you need to modify the request path in the Python script. If the new data type requires different permissions, you must also update the OAuth scopes.

Ensure that you are running the following steps and terminal commands from the root of your health-grpc-codelab directory, and that your Python virtual environment is still active.

Update scopes in the Google Cloud console

If the new data type is not covered by your existing permissions:

  1. In the Google Cloud console, go to APIs & Services > OAuth consent screen (or Data Access for Google Health API settings).
  2. Add the required scope corresponding to the new data type.
  3. Save the configuration.

Update client.py

Modify the configuration and the query path inside client.py as follows:

  1. Update the SCOPES list at the top of the file to match the new permission scopes added in the Google Cloud console.
  2. Locate the following code block inside your fetch_health_data_grpc function:
    # 3. Request data points for data type "exercise"
    print("Sending ListDataPoints RPC...")
    request = data_points_pb2.ListDataPointsRequest(parent='users/me/dataTypes/exercise')
    response = stub.ListDataPoints(request)
    
  3. Change the parent query path from 'users/me/dataTypes/exercise' to 'users/me/dataTypes/steps' (or to another data type path).
  4. Adjust the console output formatting to match the structure of the new data type response. For example:
    # 3. Request data points for data type "steps"
    print("Sending ListDataPoints RPC for steps...")
    request = data_points_pb2.ListDataPointsRequest(parent='users/me/dataTypes/steps')
    response = stub.ListDataPoints(request)
    
    # 4. Display result
    print('--- Success ---')
    for dp in response.data_points:
        print(f"Data Point ID: {dp.name}")
        # Steps data structures contain interval and count values
        print(f"Start Time: {dp.steps.interval.start_time.ToJsonString()}")
        print(f"Count: {dp.steps.count}")
        print('----------------')
    

Clear the local token cache

The OAuth access token is cached locally. To force the authentication flow to request the new scopes, delete the local token.json file:

rm token.json

Rerun the script

Execute your updated client script to complete the authorization flow again with the updated scopes and print the fetched data:

python3 client.py

9. Congratulations

Congratulations!

You have successfully set up a Google Cloud desktop client ID, configured a Python environment, retrieved and compiled the Google Health API proto schemas, and performed an end-to-end authenticated gRPC request to fetch health and fitness data.

Feel free to customize your client.py script to fetch other data types (such as steps or sleep), filter queries using intervals, or write data points using standard gRPC endpoints.

For more information: