googleapis / googleapis/google-cloud-python

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

Abierto
#16,206 1 comentario 0 reacciones 1 asignado Reclamado por @gkevinzheng Ver en GitHub
priority: p2 type: bug
Lenguaje dominante
Python
Estrellas
5.4k
Forks
1.8k
Merge medio
3 d 4 h
PR fusionados (30 d)
122

Descripción

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

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.