googleapis / googleapis/google-cloud-python

Bug: REST transport URL-encodes $alt as %24alt, causing API errors

Ouverte
#16,206 1 commentaire 0 réactions 1 personne assignée Réclamée par @gkevinzheng Voir sur GitHub
priority: p2 type: bug
Langage dominant
Python
Étoiles
5.4k
Forks
1.8k
Merge moyen
3 j 4 h
PR mergées (30 j)
122

Description

The generated REST transport passes query parameters to the `requests` library via the `params` argument, which causes the `$` character in `$alt` to be URL-encoded as `%24`. This results in API errors because the server does not recognize `%24alt` as a valid field.

### Environment

- Affected: All generated REST transports that use `$alt` parameter
- Confirmed in: `google-cloud-aiplatform` (MatchService, etc.)

### Reproduction

**Minimal case demonstrating the encoding issue:**

```python
import requests

req = requests.Request(
'POST',
'https://example.com/api',
params=[('$alt', 'json;enum-encoding=int')]
)
prepared = req.prepare()
print(prepared.url)
# Output: https://example.com/api?%24alt=json%3Benum-encoding%3Dint
# ^ $alt is incorrectly encoded as %24alt
```

**SDK reproduction (using google-cloud-aiplatform as example):**

```python
from google.cloud import aiplatform

aiplatform.init(api_transport="rest")
endpoint = aiplatform.MatchingEngineIndexEndpoint(endpoint_id)

# This fails with the error below
endpoint.find_neighbors(
deployed_index_id=deployed_index_id,
queries=[[1.0] * 768],
num_neighbors=10,
)
```

### Error Message

```
google.api_core.exceptions.BadRequest: 400 POST
https://.vdb.vertexai.goog/v1beta1/.../findNeighbors?%24alt=json%3Benum-encoding%3Dint:
Could not find field "%24alt" in the type "google.cloud.aiplatform.v1beta1.FindNeighborsRequest".
```

### Root Cause

The issue is in the generated `_get_response` method in `_shared_macros.j2`:

```python
# gapic/templates/%namespace/%name_%version/%sub/services/%service/_shared_macros.j2

response = {{ await_prefix }}getattr(session, method)(
"{host}{uri}".format(host=host, uri=uri),
timeout=timeout,
headers=headers,
params=rest_helpers.flatten_query_params(query_params, strict=True), # <- Problem here
...
)
```

When `params` is passed to `requests`, it URL-encodes special characters including `$`.

### Suggested Fix

Build the query string manually to prevent encoding of `$`:

```python
from urllib.parse import urlencode

query_string = urlencode(
rest_helpers.flatten_query_params(query_params, strict=True),
safe='$' # Do not encode $
)
url = "{host}{uri}".format(host=host, uri=uri)
if query_string:
url = f"{url}?{query_string}"

response = {{ await_prefix }}getattr(session, method)(
url,
timeout=timeout,
headers=headers,
...
)
```

### Related Issues

- googleapis/python-aiplatform#5848
- googleapis/python-aiplatform#5467

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.