Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad encoding in query parameters with new TestClient using httpx.Client #5646

Closed
9 tasks done
azogue opened this issue Nov 15, 2022 · 7 comments · Fixed by #5659
Closed
9 tasks done

Bad encoding in query parameters with new TestClient using httpx.Client #5646

azogue opened this issue Nov 15, 2022 · 7 comments · Fixed by #5659
Labels
question Question or problem question-migrate

Comments

@azogue
Copy link
Contributor

azogue commented Nov 15, 2022

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

import logging

from fastapi import FastAPI

app = FastAPI()


@app.get("/example")
async def _show_encoding_error(look_for: str):
    return {"found": look_for}


if __name__ == '__main__':
    from fastapi.testclient import TestClient

    with TestClient(app) as client:
        params = {"look_for": "plain text"}
        resp = client.get("/example", params=params).json()
        logging.warning(resp)
        assert resp["found"] == "plain text"

        params = {"look_for": "España"}
        resp = client.get("/example", params=params).json()
        logging.warning(resp)
        assert resp["found"] == "España", resp["found"]

Description

After the change to httpx for the TestClient in v0.87.0, the query parameters are not properly encoded? when sending requests with it, and strings are corrupted when received in the endpoints.

The example app works as expected if called from the SwaggerUI or from another python process using a plain httpx.Client, so it appears something broke with the new wrapping for TestClient 🥲

import httpx

params = {"look_for": "España"}
with httpx.Client(base_url="http://localhost:8000/") as client:
    resp = client.get("/example", params=params).json()
    assert resp["found"] == "España"

Operating System

macOS

Operating System Details

M1, running arm64 arch

FastAPI Version

0.87.0

Python Version

Python 3.10.5

Additional Context

starlette-0.21
httpx-0.23.0

Discovered when trying to migrate the test suite for a ~big project previously using fastapi-0.85.1 + starlette-0.20.4.

All minor syntax changes from old requests to new httpx were under control, but in one unit test, a string with an accent was making some search to fail without results (test is sending "Formalización" but endpoint is receiving "Formalización" 😱), and I was getting crazy 😅

@azogue azogue added the question Question or problem label Nov 15, 2022
@azogue
Copy link
Contributor Author

azogue commented Nov 15, 2022

I just saw this it is not related to FastAPI but to Starlette 😅, after encode/starlette#1376, and the example code above fails the same way if using the original object from starlette.testclient import TestClient

I'll try to ask there 👍

Not sure if closing this one, as starlette version is pinned to 0.21.0 because of the TestClient change

@azogue
Copy link
Contributor Author

azogue commented Nov 16, 2022

For those in a hurry, or just to quick-check that the strange broken tests you're having after the TestClient change to httpx are related to this,

pip install https://lexic-public-assets.s3.eu-west-1.amazonaws.com/wheels/universal/starlette-0.21.0-py3-none-any.whl

will swap the published version with a fixed one containing encode/starlette#1953 👍

@Kludex
Copy link
Sponsor Collaborator

Kludex commented Nov 18, 2022

This is solved in Starlette 0.22.0.

@mezhaka
Copy link

mezhaka commented Nov 18, 2022

@Kludex What is the plan to fix it in FastAPI? Is there a PR that pulls in the Starlette 0.22.0? The Starlette 0.22.0 is already out.

@azogue
Copy link
Contributor Author

azogue commented Nov 18, 2022

@Kludex What is the plan to fix it in FastAPI? Is there a PR that pulls in the Starlette 0.22.0? The Starlette 0.22.0 is already out.

@mezhaka ,

in #5659, but I'm new here 😅, so not sure about the workflow to generate patches, sorry

@mezhaka
Copy link

mezhaka commented Nov 18, 2022

@azogue Nice, even with a test!

@tiangolo
Copy link
Owner

Thanks @azogue for reporting and upgrading it here! 🍰

Thanks everyone for the discussion too! ☕

This is available in FastAPI 0.88.0, just released. 🚀

@tiangolo tiangolo reopened this Feb 27, 2023
Repository owner locked and limited conversation to collaborators Feb 27, 2023
@tiangolo tiangolo converted this issue into discussion #6190 Feb 27, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
4 participants