Skip to content

Commit

Permalink
Update to pydantic v2 farmOS#59
Browse files Browse the repository at this point in the history
  • Loading branch information
paul121 committed Mar 14, 2024
1 parent e1c9c17 commit 9e2c960
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 21 deletions.
40 changes: 21 additions & 19 deletions farmOS/subrequests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
from enum import Enum
from typing import Any, Dict, List, Optional, Union
from typing import Any, Dict, Iterator, List, Optional, Union

from pydantic import BaseModel, Field, validator
from pydantic import BaseModel, RootModel, Field, field_validator, model_validator

# Subrequests model derived from provided JSON Schema
# https://git.drupalcode.org/project/subrequests/-/blob/3.x/schema.json
Expand Down Expand Up @@ -52,26 +52,28 @@ class Subrequest(BaseModel):
title="Parent ID",
)

@validator("uri", pre=True, always=True)
def check_uri_or_endpoint(cls, uri, values):
endpoint = values.get("endpoint", None)
if uri is None and endpoint is None:
@model_validator(mode="after")
def check_uri_or_endpoint(self):
# endpoint = values.get("endpoint", None)
if self.uri is None and self.endpoint is None:
raise ValueError("Either uri or endpoint is required.")
return uri
return self.uri

@validator("body", pre=True)
@field_validator("body")
def serialize_body(cls, body):
if not isinstance(body, str):
return json.dumps(body)
return body


class SubrequestsBlueprint(BaseModel):
__root__: List[Subrequest] = Field(
...,
description="Describes the subrequests payload format.",
title="Subrequests format",
)
class SubrequestsBlueprint(RootModel):
root: List

def __iter__(self) -> Iterator[Subrequest]:
return iter(self.root)

def __getitem__(self, item) -> Subrequest:
return self.root[item]


class Format(str, Enum):
Expand All @@ -93,10 +95,10 @@ def send(
format: Optional[Union[Format, str]] = Format.json,
):
if isinstance(blueprint, List):
blueprint = SubrequestsBlueprint.parse_obj(blueprint)
blueprint = SubrequestsBlueprint(blueprint)

# Modify each sub-request as needed.
for sub in blueprint.__root__:
for sub in blueprint:
# Build the URI if an endpoint is provided.
if sub.uri is None and sub.endpoint is not None:
sub.uri = sub.endpoint
Expand All @@ -114,16 +116,16 @@ def send(
if format == Format.json.value:
params = {"_format": "json"}

# Generate the json to send. It is important to use the .json() method
# Generate the json to send. It is important to use the .model_dump_json() method
# of the model for correct serialization.
json = blueprint.json(exclude_none=True)
blueprint_json = blueprint.model_dump_json(exclude_none=True)

response = self.client.request(
method="POST",
url=self.subrequest_path,
params=params,
headers={"Content-Type": "application/json"},
content=json,
content=blueprint_json,
)

# Return a json response if requested.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"pytest-runner",
]

install_requires = ["httpx~=0.26", "httpx_auth~=0.20", "pydantic~=1.7.3"]
install_requires = ["httpx~=0.26", "httpx_auth~=0.20", "pydantic~=2.0"]

extras_require = {
"test": ["pytest~=7.0", "black~=23.0", "setuptools~=68.0"],
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_subrequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def test_subrequests(test_farm):
)

# Create a blueprint object
blueprint = SubrequestsBlueprint.parse_obj([new_plant_type, new_asset, new_log])
blueprint = SubrequestsBlueprint([new_plant_type, new_asset, new_log])

# Send the blueprint.
post_response = test_farm.subrequests.send(blueprint, format=Format.json)
Expand Down

0 comments on commit 9e2c960

Please sign in to comment.