Skip to content

Supporting Response(content=..., text=..., html=..., json=...) #1227

Closed

Description

@lovelydinosaur

We’d like to support instantiating Response instances directly.

One really good example of why we might want to do that is for unit testing custom auth classes - #1217 (comment)

Currently Response instances are only ever created by the client itself, and...

  • Have a mandatory request=... parameter.
  • Have a mandatory status_code parameter.

The first things we should do here are:

  • Make the request parameter become optional. Have a .request property that returns a Request instance or raises a RuntimeError if the instance is not set. Have a property setter for the .request property.
  • Make the status code be enforced as kwarg-only, and make it optional, with a default of 200.

Once we’ve done those things we should add support for setting the content of a response, using content=..., text=..., html=..., json=... parameters, which mirror the request parameters of data=..., files=..., json=..., but differ because HTTP responses use different content types to HTTP requests.

The encode(...) method in content_streams.py would become encode_request_body(data=..., files=..., json=..., boundary=...), and would be mirrored by a encode_response_body(content=..., text=..., html=..., json=...) method, which would use the following content streams:

  • content - Support either bytes or byte iterator/aiterators. Setting Content-Length or Transfer-Encoding: chunked
  • text - Set Content-Type: text/plain; charset=“utf-8” , and a Content-Length header.
  • html - Set Content-Type: text/html; charset=“utf-8” and a Content-Length header.
  • json - Set Content-Type: application/json and a Content-Length header.

We can tie in an encoding=... argument too, but let’s talk that through as a follow up.

What this would then all give us is the ability to create responses like so...

response = httpx.Response(json={“hello”: “world”})
response = httpx.Response(html=“<body><h1>hello, world</h1></body>”})
response = httpx.Response(text=“Not found”, status_code=404)
response = httpx.Response(content=b’...’, headers=...)

Somewhat refs #1091

Activity

  1. added this to the v1.0 milestone on Aug 27, 2020
  2. lovelydinosaur commented on Aug 27, 2020

    @lovelydinosaur
    MemberAuthor

    If any contributors want to take a go at this I'd suggest approaching it in parts...

    • Issue a PR for making the request=... parameter not mandatory.
    • Issue a PR making status_code a keyword-only argument, and defaulting it to 200.
    • Issue a PR with the response body encoding handling (more complex than the other two.)
  3. Pradhvan commented on Aug 27, 2020

    @Pradhvan

    The issue is quite detailed thanks for that. 😄 I don't have much experience with httpx but would love to give it a try.

  4. lovelydinosaur commented on Aug 27, 2020

    @lovelydinosaur
    MemberAuthor

    Great. Definitely treat each of those items in isolation as separate PRs. 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions