schemathesis: [BUG] starlette 0.21.0 uses httpx testclient
Checklist
- I checked the FAQ section of the documentation
- I looked for similar issues in the issue tracker
Describe the bug
starlette==0.21.0
updated to use httpx
for the testclient instead of requests
.
In particular starlette.testclient.TestClient
now inherits httpx.Client
.
To Reproduce
Use Case.call_asgi(...)
in a unit test.
Error:
File "/mnt/win/work/nightcrawler/tests/schema/lookup/test_txt.py", line 22, in test_txt
response = case.call_asgi(headers={'Authorization': 'Bearer supersecret'})
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/schemathesis/models.py", line 397, in call_asgi
return self.call(base_url=base_url, session=client, headers=headers, **kwargs)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/schemathesis/models.py", line 327, in call
response = session.request(**data) # type: ignore
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/starlette/testclient.py", line 448, in request
return super().request(
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_client.py", line 803, in request
request = self.build_request(
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_client.py", line 346, in build_request
headers = self._merge_headers(headers)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_client.py", line 413, in _merge_headers
merged_headers.update(headers)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_models.py", line 199, in update
headers = Headers(headers)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_models.py", line 79, in __init__
self._list = [
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/httpx/_models.py", line 85, in <listcomp>
for k, v in headers
ValueError: too many values to unpack (expected 2)
Falsifying example: test_txt(
case=Case(path_parameters={'domain': 'A.ac'}, headers={'Authorization': 'Bearer '}, query={}),
self=<tests.schema.lookup.test_txt.TestTXTSchema testMethod=test_txt>,
)
Additional context
I forced the headers to be a dict instead of a requests.structures.CaseInsensitiveDict
and that furthered the state, but it next up failed with:
File "/mnt/win/work/nightcrawler/tests/schema/lookup/test_txt.py", line 23, in test_txt
case.validate_response(response)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/schemathesis/models.py", line 424, in validate_response
copied_response = copy_response(response)
File "/mnt/win/work/nightcrawler/.pyenv/lib/python3.10/site-packages/schemathesis/utils.py", line 279, in copy_response
response.freeze()
AttributeError: 'Response' object has no attribute 'freeze'
Falsifying example: test_txt(
case=Case(path_parameters={'domain': 'A.ac'}, headers={'Authorization': 'Bearer '}, query={}),
self=<tests.schema.lookup.test_txt.TestTXTSchema testMethod=test_txt>,
)
This seems to be caused by now getting a httpx.Response
back instead of a requests.Response
, and these objects are very different.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 19 (9 by maintainers)
Commits related to this issue
- Small fix to handle httpx response Fix for https://github.com/schemathesis/schemathesis/issues/1637 — committed to SatelCreative/schemathesis by hillairet 2 years ago
Sorry for the delay!
I ran with the approach suggested by @Kludex and it will be available in the next version soon. However, I’d like to overhaul transports properly as it unblocks a few nice things (like a unified interface to requests/WSGI/ASGI responses and adding more transports in the future, etc). I’ll create a separate issue for that
@Stranger6667 if it is going to take a while to address this issue, in the meantime please can the
pyproject.toml
be corrected to specify its dependency on the appropriate version of starlette?https://github.com/schemathesis/schemathesis/blob/master/pyproject.toml#L52 at the moment this is specified as
starlette = ">=0.13,<1"
which is incorrect, since schemathesis is not compatible with starlette>=0.21. It should bestarlette = ">=0.13,<0.21"
@Stranger6667 You can ping me on those issues, I can help.
Please do not restrict the range of versions of Starlette. You can replace the Starlette
TestClient
by this one: https://github.com/Kludex/starlette-testclient; and I’ve also created this tool to help on the bump: https://github.com/Kludex/bump-testclient.As a consequence
FastAPI >= 0.87.0
is also affected since it usesStarlette >= 0.21.0
. So thank you in advance for handlinghttpx
. 🙏Oh, right. Thank you for opening this issue. I’ll take a look this evening
@tmeckel You’re very welcome! 😃
@Stranger6667 Dammit! So obvious!!! This solved the issue. Thanks for helping!
Thank you for sharing the code! I believe you need to pass
starlette_client.TestClient
instance on line 105, instead of the one fromstarlette
@tmeckel Could you, please, share the
test_api
function definition + how you load your schema (schemathesis.from_*
call)?This will take some more time as it requires full support for
httpx
, so all built-in checks, hooks, the runner integration, etc should be updated.