Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

context based dynamic serialization #27

Merged
merged 1 commit into from
Apr 22, 2024

Conversation

sbasan
Copy link
Contributor

@sbasan sbasan commented Apr 18, 2024

Pull Request summary:

It is now possible to have different serialization alias to be chosen dynamically based on running Manager api version.
This extends the possibility to reuse single payload model definition for different Manager API versions.

We are utilizing a new feature introduced in pydantic 2.7.0 Ability to pass a context object to the serialization methods.
Context dict containing api_version key is provided before sending payload automatically when using methods decorated with @post, @put etc.
When model fields are annotated with VersionedField - model_serializer updates fields using helper when api_version is given in context.

  • introduce VersionedField annotation
  • introduce update_model_fields() helper
  • automatically inject context containing api_version when dumping model before payload is sent

Full usage example:

from catalystwan.models.common import VersionedField
from pydantic import BaseModel, model_serializer
from typing_extensions import Annotated
from catalystwan.endpoints import APIEndpoints, post
from catalystwan.session import create_manager_session


# 1. provide annotation with matching version specifier and desired serialization_alias
class TestPayload(BaseModel):
    data: Annotated[
        bool,
        VersionedField(versions=">=20.13,<20.15", serialization_alias="dataForApiBefore-20.15"),
        VersionedField(versions=">=20.15", serialization_alias="dataForApiAfter-20.15"),
    ] = True

    # 2. provide model_serializer which utilize helper
    @model_serializer(mode="wrap")
    def serialize(self, handler, serialization_info):
        return VersionedField.update_model_fields(self.model_fields, handler(self), serialization_info)


class CustomAPI(APIEndpoints):

    @post("/test")
    def test_create(payload: TestPayload) -> None:
        ...


with create_manager_session(**login) as session:
    api = CustomAPI(session)
    api.test_create(payload=TestPayload()) # serialization alias is determined in runtime according to matching api version

Checklist:

  • Make sure to run pre-commit before committing changes
  • Make sure all checks have passed
  • PR description is clear and comprehensive
  • Mentioned the issue that this PR solves (if applicable)
  • Make sure you test the changes

@sbasan sbasan force-pushed the fr/version-aware-serialization branch from f0baff1 to 3dfd23b Compare April 18, 2024 11:39
@sbasan sbasan requested review from jpkrajewski and smialy April 18, 2024 12:30
@sbasan sbasan merged commit 3020907 into dev-uxmt Apr 22, 2024
10 checks passed
@sbasan sbasan deleted the fr/version-aware-serialization branch April 22, 2024 09:51
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants