Skip to content

Commit

Permalink
Merge pull request #208 from leiserfg/complex-pydantic-model
Browse files Browse the repository at this point in the history
Add support for complex pydantic models
  • Loading branch information
prkumar committed Nov 17, 2020
2 parents 73ea8ae + 4f8538a commit ee3c763
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
22 changes: 22 additions & 0 deletions tests/unit/test_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,28 @@ def test_create_request_body_converter(self, pydantic_model_mock):

assert result == expected_result
model_mock.dict.assert_called_once()
model_mock.dict.assert_called_once()

def test_convert_complex_model(self):
from json import loads
from datetime import datetime
from typing import List

class ComplexModel(pydantic.BaseModel):
when = datetime.utcnow() # type: datetime
where = 'http://example.com' # type: pydantic.AnyUrl
some = [1] # type: List[int]

model = ComplexModel()
request_body = {}
expected_result = loads(model.json())

converter = converters.PydanticConverter()
request_converter = converter.create_request_body_converter(ComplexModel)

result = request_converter.convert(request_body)

assert result == expected_result

def test_create_request_body_converter_without_schema(self, mocker):
expected_result = None
Expand Down
19 changes: 18 additions & 1 deletion uplink/converters/pydantic_.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,29 @@
from uplink.utils import is_subclass


def _encode_pydantic(obj):
from pydantic.json import pydantic_encoder

# json atoms
if isinstance(obj, (str, int, float, bool)) or obj is None:
return obj

# json containers
if isinstance(obj, dict):
return {_encode_pydantic(k): _encode_pydantic(v) for k, v in obj.items()}
if isinstance(obj, list):
return [_encode_pydantic(i) for i in obj]

# pydantic types
return _encode_pydantic(pydantic_encoder(obj))


class _PydanticRequestBody(Converter):
def __init__(self, model):
self._model = model

def convert(self, value):
return self._model(**value).dict()
return _encode_pydantic(self._model.parse_obj(value))


class _PydanticResponseBody(Converter):
Expand Down

0 comments on commit ee3c763

Please sign in to comment.