List query parameters are percent-encoded twice
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python
- Domain
- backend, networking
Research direction
Locate build_query_param and run the provided httpx.MockTransport reproduction to inspect the decoded collection_refs parameter. Check nearby query-parameter tests and add coverage for reserved characters; completion means list items are encoded only once and the reproduction reports food:pizza.
Written by the indexing model from the issue text.
Description
Description
build_query_param percent-encodes each item of a list parameter with urllib.parse.quote before it joins the items with commas. httpx then encodes the whole query string again, so every character that quote escapes reaches the server double-encoded.
For example, client.feeds.read_collections(collection_refs=["food:pizza"]) sends:
GET /api/v2/feeds/collections?collection_refs=food%253Apizza
The server decodes this once to food%3Apizza instead of food:pizza. Collection references always contain :, so read_collections and delete_collections cannot match any collection. The same applies to any list parameter item that contains a space, :, @, , or another reserved character, for example in get_many_messages(ids=...), member_custom_include and the moderation ids.
getstream-go and stream-node join list items with commas and encode the query string once, so they send collection_refs=food%3Apizza.
Steps to reproduce
import httpx
from getstream import Stream
seen = []
client = Stream(
api_key="key",
api_secret="secret",
transport=httpx.MockTransport(
lambda r: seen.append(r)
or httpx.Response(200, json={"duration": "0ms", "collections": []})
),
)
client.feeds.read_collections(collection_refs=["food:pizza"])
print(seen[0].url.params["collection_refs"])
Expected output: food:pizza
Actual output: food%3Apizza
- Dominant language
- Python
- Stars
- 25
- Forks
- 14
- Avg merge
- 18h 23m
- Merged PRs (30d)
- 12
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from GetStream/stream-py
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
GetStream/stream-py#293 · 10 comments ·
Maintainers usually reply within 1 day
-
RuntimeError: generator didn't yield in telemetry wrapper with Python 3.12.10+ (getstream 2.5.x)Open
Difficulty 3/5 1-2 days Newbie friendliness 42/100
GetStream/stream-py#161 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 30/100
Maintainers usually reply within 1 day
All issues in GetStream/stream-py
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 60/100
521xueweihan/HelloGitHub#3924 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
wilbowes/EchoMuse#869 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
namespace operations
Difficulty 1/5 Under an hour Newbie friendliness 72/100
EclipseFdn/open-vsx.org#14043 ·
Maintainers usually reply within 1 day
-
test: TestServeUntilStale races the server's close against the client's sendall (BrokenPipeError under load)Possibly taken @evoludigit claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 89/100
Maintainers usually reply within 1 day