pythongoogle-mapsgoogle-cloud-platformgoogle-routes-api

How to serialize a ComputeRoutesResponse


When using the web endpoint with python requests for computing Routes with Google Cloud, https://routes.googleapis.com/directions/v2:computeRoutes, I get the response in json. This is how I build the request with python, it allows me to work better with data received.

headers = {
    'Content-Type': 'application/json',
    'X-Goog-Api-Key': API_KEY,
    'X-Goog-FieldMask': 'routes.duration,routes.distanceMeters,routes.legs,routes.optimizedIntermediateWaypointIndex,geocodingResults',
}
data = {
    'origin': {
        'placeId': ORIGIN_ID
    },
    'destination': {
        'placeId': DESTINATION_ID
    },
    'intermediates': intermediates,
    'travelMode': 'DRIVE',
    'routingPreference': 'TRAFFIC_AWARE',
    'departureTime': '2024-07-06T10:00:00Z',
    'computeAlternativeRoutes': False,
    'optimizeWaypointOrder': True,
    'units': 'METRIC',
}
response = requests.post('https://routes.googleapis.com/directions/v2:computeRoutes', headers=headers, json=data, timeout=25)

I want to use the python library directly, but the response from the API comes in the form of a protobuff message and when trying to save the response as Json I get the error:

TypeError: Object of type ComputeRoutesResponse is not JSON serializable

This is how I build the request in python:

routes_client = RoutesClient()
route_response = routes_client.compute_routes(
    ComputeRoutesRequest(
        destination=Waypoint(
            address=DESTINATION_PLUS_CODE
        ),
        origin=Waypoint(
            address=ORIGIN_PLUS_CODE
        ),
        intermediates=intermediates,
        travel_mode='DRIVE',
        region_code='US',
        routing_preference='TRAFFIC_AWARE',
        departure_time=datetime.now(tz=timezone('America/Los_Angeles'))+timedelta(days=1),
        compute_alternative_routes=False,
        units='METRIC',
        optimize_waypoint_order=True,
    ),
    metadata=[("x-goog-fieldmask", ','.join(field_mask))]
)

I tried adding ("content-type", 'application/json') to the metadata but does not work either.

What could I do to serialize the result so I can save it for later processing.


Solution

  • I investigated further.

    Google Cloud Client libraries for Python use proto-plus

    proto-plus includes serialization methods so you can:

    route_response = ...
    
    # NOTE: 'to_json` is a class method
    ComputeRoutesResponse.to_json(route_response)
    

    to_json does additional formatting work but is essentially:

    route_response = ...
    
    # NOTE: 'pb' is a class method
    msg = ComputeRoutesResponse.pb(route_response)
    j = MessageToJson(msg)
    print(j)