From dd2d49c30309fbd42492c6c79f3c1f5b2c6d4eac Mon Sep 17 00:00:00 2001 From: Guillaume Gauvrit Date: Sat, 20 Jan 2024 15:42:20 +0100 Subject: [PATCH] Add a x-www-form-urlencoded url encoded serializer --- src/blacksmith/service/request_serializer.py | 14 ++++++++++++- tests/unittests/test_request_serializer.py | 21 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/blacksmith/service/request_serializer.py b/src/blacksmith/service/request_serializer.py index fbe96a61..9b056799 100644 --- a/src/blacksmith/service/request_serializer.py +++ b/src/blacksmith/service/request_serializer.py @@ -11,6 +11,7 @@ Union, cast, ) +from urllib.parse import urlencode from pydantic import BaseModel, SecretBytes, SecretStr from pydantic.fields import FieldInfo @@ -64,6 +65,14 @@ def serialize(self, body: Dict[str, Any] | Sequence[Any]) -> str: return json.dumps(body, cls=JSONEncoder) +class UrlencodedRequestSerializer(AbstractRequestBodySerializer): + def accept(self, content_type: str) -> bool: + return content_type == "application/x-www-form-urlencoded" + + def serialize(self, body: Dict[str, Any] | Sequence[Any]) -> str: + return urlencode(body, doseq=True) + + class JSONEncoder(json.JSONEncoder): def default(self, o: Any) -> Any: for typ, serializer in ENCODERS_BY_TYPE.items(): @@ -120,7 +129,10 @@ def serialize_part(req: "Request", part: Dict[IntStr, Any]) -> Dict[str, simplet } -SERIALIZERS: list[AbstractRequestBodySerializer] = [JsonRequestSerializer()] +SERIALIZERS: list[AbstractRequestBodySerializer] = [ + JsonRequestSerializer(), + UrlencodedRequestSerializer(), +] """Serializers to """ diff --git a/tests/unittests/test_request_serializer.py b/tests/unittests/test_request_serializer.py index 7f4df2f5..5349d02c 100644 --- a/tests/unittests/test_request_serializer.py +++ b/tests/unittests/test_request_serializer.py @@ -17,6 +17,7 @@ QUERY, JSONEncoder, JsonRequestSerializer, + UrlencodedRequestSerializer, get_location, serialize_body, serialize_part, @@ -235,6 +236,16 @@ def test_serializer_request(params: Mapping[str, Any]): "accept": "text/xml", "expected": False, }, + { + "srlz": UrlencodedRequestSerializer(), + "accept": "application/x-www-form-urlencoded", + "expected": True, + }, + { + "srlz": UrlencodedRequestSerializer(), + "accept": "text/xml", + "expected": False, + }, ], ) def test_request_serializer_accept(params: Mapping[str, Any]): @@ -250,6 +261,16 @@ def test_request_serializer_accept(params: Mapping[str, Any]): "data": {"foo": "bar"}, "expected": '{"foo": "bar"}', }, + { + "srlz": UrlencodedRequestSerializer(), + "data": {"foo": "bar"}, + "expected": "foo=bar", + }, + { + "srlz": UrlencodedRequestSerializer(), + "data": {"foo": ["bar", "baz"]}, + "expected": "foo=bar&foo=baz", + }, ], ) def test_request_serializer_serialize(params: Mapping[str, Any]):