Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- update docs
- don't encode value in case it has already the right type
  • Loading branch information
devkral committed Nov 25, 2024
1 parent af16318 commit eafc554
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
16 changes: 13 additions & 3 deletions docs/en/docs/encoders.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ from esmerald.encoders import Encoder

When subclassing the `Encoder`, the mandatory functions are:

**Serializing**
* [`is_type()`](#is_type)
* [`serialize()`](#serialize)


**Molding**

* [`is_type()`](#is_type)
* [`is_type_structure()`](#is_type_structure)
* [`encode()`](#encode)

Esmerald extends the native functionality of Lilya regarding the encoders and adds some extra flavours to it.
Expand All @@ -43,9 +50,6 @@ unique to Esmerald.
This function might sound confusing but it is in fact something simple. This function is used to check
if the object of type X is an instance or a subclass of that same type.

!!! Danger
Here is where it is different from Lilya. With Lilya you can use the `__type__` as well but
**not in Esmerald. In Esmerald you must implement the `is_type` function.

#### Example

Expand All @@ -71,6 +75,11 @@ Quite simple and intuitive.
{!> ../../../docs_src/encoders/serialize.py !}
```

### is_type_structure

For checking if an annotation can be used to mold an instance from the value.
In the second step it is verified via `is_type` if the molding is required of the type or the type does match already.

### encode

Finally, this functionality is what converts a given piece of data (JSON usually) into an object
Expand All @@ -84,6 +93,7 @@ For example, a dictionary into Pydantic models or MsgSpec Structs.
{!> ../../../docs_src/encoders/encode.py !}
```


### The flexibility

As you can see, there are many ways of you building your encoders. Esmerald internally already brings
Expand Down
11 changes: 6 additions & 5 deletions docs_src/encoders/encode.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@


class MsgSpecEncoder(Encoder):

def is_type(self, value: Any) -> bool:
return isinstance(value, Struct) or is_class_and_subclass(value, Struct)
return isinstance(value, Struct)

def is_type_structure(self, value: Any) -> bool:
return is_class_and_subclass(value, Struct)

def serialize(self, obj: Any) -> Any:
return msgspec.json.decode(msgspec.json.encode(obj))
Expand All @@ -23,9 +25,8 @@ def encode(self, annotation: Any, value: Any) -> Any:


class PydanticEncoder(Encoder):

def is_type(self, value: Any) -> bool:
return isinstance(value, BaseModel) or is_class_and_subclass(value, BaseModel)
# leverage the comfort lilya is_type and is_type_structure defaults
__type__ = BaseModel

def serialize(self, obj: BaseModel) -> dict[str, Any]:
return obj.model_dump()
Expand Down
2 changes: 1 addition & 1 deletion esmerald/transformers/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def encode_value(encoder: "Encoder", annotation: Any, value: Any) -> Any:
Returns:
Any: The encoded value if the encoder is valid, otherwise the original value.
"""
if hasattr(encoder, "encode"):
if hasattr(encoder, "encode") and not encoder.is_type(value):
return encoder.encode(annotation, value)
return value

Expand Down

0 comments on commit eafc554

Please sign in to comment.