googleapis / googleapis/google-cloud-python

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

オープン
#16,206 コメント 1 件 リアクション 0 件 担当者 1 名 @gkevinzheng が担当を希望しています GitHub で見る
priority: p2 type: bug
主要言語
Python
スター
5.4k
フォーク
1.8k
平均マージ
3日 4時間
マージ済み PR(30日)
122

説明

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

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。