Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/ahttpx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .__version__ import __title__, __version__
from ._client import * # Client
from ._connection import * # Connection, Transport
from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text
from ._content import * # Binary, Content, File, Files, Form, HTML, JSON, MultiPart, Text
from ._headers import * # Headers
from ._network import * # NetworkBackend, NetworkStream, timeout
from ._parsers import * # HTTPParser, HTTPStream, ProtocolError
Expand All @@ -18,6 +18,7 @@
__all__ = [
"__title__",
"__version__",
"Binary",
"ByteStream",
"Client",
"Connection",
Expand Down
51 changes: 41 additions & 10 deletions src/ahttpx/_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ._urlencode import urldecode, urlencode

__all__ = [
"Binary",
"Content",
"Form",
"File",
Expand Down Expand Up @@ -36,6 +37,9 @@ def open(self) -> Stream:
def content_type(self) -> str:
raise NotImplementedError()

def __bytes__(self):
raise TypeError(f"Content {self.__class__.__name__} does not support a bytes interface.")


class Form(typing.Mapping[str, str], Content):
"""
Expand Down Expand Up @@ -73,12 +77,12 @@ def __init__(
d.setdefault(k, []).append(v)

self._dict = d
self._content = str(self).encode("ascii")

# Content API

def open(self) -> Stream:
content = str(self).encode("ascii")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "application/x-www-form-urlencoded"
Expand Down Expand Up @@ -289,53 +293,80 @@ def __repr__(self) -> str:
class JSON(Content):
def __init__(self, data: typing.Any) -> None:
self._data = data

def open(self) -> Stream:
content = json.dumps(
self._content = json.dumps(
self._data,
ensure_ascii=False,
separators=(",", ":"),
allow_nan=False
).encode("utf-8")
return ByteStream(content)

def open(self) -> Stream:
return ByteStream(self._content)

def content_type(self) -> str:
return "application/json"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<JSON {self._data!r}>"


class Text(Content):
def __init__(self, text: str) -> None:
self._text = text
self._content = self._text.encode("utf-8")

def open(self) -> Stream:
content = self._text.encode("utf-8")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "text/plain; charset='utf-8'"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<Text {self._text!r}>"


class HTML(Content):
def __init__(self, text: str) -> None:
self._text = text
self._content = self._text.encode("utf-8")

def open(self) -> Stream:
content = self._text.encode("utf-8")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "text/html; charset='utf-8'"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<HTML {self._text!r}>"


class Binary(Content):
def __init__(self, content: bytes, content_type: str) -> None:
self._content = content
self._content_type = content_type

def open(self) -> Stream:
return ByteStream(self._content)

def content_type(self) -> str:
return self._content_type

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<Binary {self._content!r}>"


class MultiPart(Content):
def __init__(
self,
Expand Down
3 changes: 2 additions & 1 deletion src/httpx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .__version__ import __title__, __version__
from ._client import * # Client
from ._connection import * # Connection, Transport
from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text
from ._content import * # Binary, Content, File, Files, Form, HTML, JSON, MultiPart, Text
from ._headers import * # Headers
from ._network import * # NetworkBackend, NetworkStream, timeout
from ._parsers import * # HTTPParser, HTTPStream, ProtocolError
Expand All @@ -18,6 +18,7 @@
__all__ = [
"__title__",
"__version__",
"Binary",
"ByteStream",
"Client",
"Connection",
Expand Down
51 changes: 41 additions & 10 deletions src/httpx/_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ._urlencode import urldecode, urlencode

__all__ = [
"Binary",
"Content",
"Form",
"File",
Expand Down Expand Up @@ -36,6 +37,9 @@ def open(self) -> Stream:
def content_type(self) -> str:
raise NotImplementedError()

def __bytes__(self):
raise TypeError(f"Content {self.__class__.__name__} does not support a bytes interface.")


class Form(typing.Mapping[str, str], Content):
"""
Expand Down Expand Up @@ -73,12 +77,12 @@ def __init__(
d.setdefault(k, []).append(v)

self._dict = d
self._content = str(self).encode("ascii")

# Content API

def open(self) -> Stream:
content = str(self).encode("ascii")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "application/x-www-form-urlencoded"
Expand Down Expand Up @@ -289,53 +293,80 @@ def __repr__(self) -> str:
class JSON(Content):
def __init__(self, data: typing.Any) -> None:
self._data = data

def open(self) -> Stream:
content = json.dumps(
self._content = json.dumps(
self._data,
ensure_ascii=False,
separators=(",", ":"),
allow_nan=False
).encode("utf-8")
return ByteStream(content)

def open(self) -> Stream:
return ByteStream(self._content)

def content_type(self) -> str:
return "application/json"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<JSON {self._data!r}>"


class Text(Content):
def __init__(self, text: str) -> None:
self._text = text
self._content = self._text.encode("utf-8")

def open(self) -> Stream:
content = self._text.encode("utf-8")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "text/plain; charset='utf-8'"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<Text {self._text!r}>"


class HTML(Content):
def __init__(self, text: str) -> None:
self._text = text
self._content = self._text.encode("utf-8")

def open(self) -> Stream:
content = self._text.encode("utf-8")
return ByteStream(content)
return ByteStream(self._content)

def content_type(self) -> str:
return "text/html; charset='utf-8'"

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<HTML {self._text!r}>"


class Binary(Content):
def __init__(self, content: bytes, content_type: str) -> None:
self._content = content
self._content_type = content_type

def open(self) -> Stream:
return ByteStream(self._content)

def content_type(self) -> str:
return self._content_type

def __bytes__(self) -> bytes:
return self._content

def __repr__(self) -> str:
return f"<Binary {self._content!r}>"


class MultiPart(Content):
def __init__(
self,
Expand Down
3 changes: 3 additions & 0 deletions tests/test_ahttpx/test_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async def test_html():

assert await stream.read() == b'<html><body>Hello, world</body></html>'
assert content_type == "text/html; charset='utf-8'"
assert bytes(html) == b'<html><body>Hello, world</body></html>'


# Text
Expand All @@ -28,6 +29,7 @@ async def test_text():

assert await stream.read() == b'Hello, world'
assert content_type == "text/plain; charset='utf-8'"
assert bytes(text) == b'Hello, world'


# JSON
Expand All @@ -41,6 +43,7 @@ async def test_json():

assert await stream.read() == b'{"data":123}'
assert content_type == "application/json"
assert bytes(data) == b'{"data":123}'


# Form
Expand Down
3 changes: 3 additions & 0 deletions tests/test_httpx/test_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def test_html():

assert stream.read() == b'<html><body>Hello, world</body></html>'
assert content_type == "text/html; charset='utf-8'"
assert bytes(html) == b'<html><body>Hello, world</body></html>'


# Text
Expand All @@ -26,6 +27,7 @@ def test_text():

assert stream.read() == b'Hello, world'
assert content_type == "text/plain; charset='utf-8'"
assert bytes(text) == b'Hello, world'


# JSON
Expand All @@ -38,6 +40,7 @@ def test_json():

assert stream.read() == b'{"data":123}'
assert content_type == "application/json"
assert bytes(data) == b'{"data":123}'


# Form
Expand Down
Loading