googleapis / googleapis/google-cloud-python

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

Đang mở
#16,206 1 bình luận 0 reaction 1 người được giao Được @gkevinzheng nhận Xem trên GitHub
priority: p2 type: bug
Ngôn ngữ chính
Python
Star
5.4k
Fork
1.8k
Merge trung bình
3 ngày 4 giờ
Pull request đã merge (30 ngày)
122

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.