|
1 |
| -from typing import List, Optional, Union |
| 1 | +from typing import List, Optional, Set, Union |
2 | 2 |
|
3 |
| -from pydantic import BaseModel, Field, conlist, root_validator |
| 3 | +from pydantic.fields import Field |
| 4 | +from pydantic.functional_validators import model_validator |
| 5 | +from pydantic.main import BaseModel |
4 | 6 |
|
5 | 7 | from jsonapi_pydantic.v1_0.error import Error
|
6 | 8 | from jsonapi_pydantic.v1_0.jsonapi import JsonApi as JsonApiObject
|
|
13 | 15 | None,
|
14 | 16 | Resource,
|
15 | 17 | ResourceIdentifier,
|
16 |
| - conlist(Resource, min_items=0, unique_items=True), |
17 |
| - conlist(ResourceIdentifier, min_items=0, unique_items=True), |
| 18 | + Set[Resource], |
| 19 | + Set[ResourceIdentifier], |
18 | 20 | ]
|
19 | 21 | Errors = Optional[List[Error]]
|
20 | 22 | Meta = Optional[MetaObject]
|
21 | 23 |
|
22 | 24 | JsonApi = Optional[JsonApiObject]
|
23 | 25 | Links = Optional[LinksObject]
|
24 |
| -Included = Optional[conlist(Resource, min_items=0, unique_items=True)] |
| 26 | +Included = Optional[Set[Resource]] |
25 | 27 |
|
26 | 28 |
|
27 | 29 | class TopLevel(BaseModel):
|
28 |
| - data: Data = Field(title="Data") |
29 |
| - errors: Errors = Field(title="Errors") |
30 |
| - meta: Meta = Field(title="Meta") |
| 30 | + data: Data = Field(None, title="Data") |
| 31 | + errors: Errors = Field(None, title="Errors") |
| 32 | + meta: Meta = Field(None, title="Meta") |
31 | 33 |
|
32 |
| - jsonapi: JsonApi = Field(title="JSON:API") |
33 |
| - links: Links = Field(title="Links") |
34 |
| - included: Included = Field(title="Included") |
| 34 | + jsonapi: JsonApi = Field(None, title="JSON:API") |
| 35 | + links: Links = Field(None, title="Links") |
| 36 | + included: Included = Field(None, title="Included") |
35 | 37 |
|
36 |
| - @root_validator |
37 |
| - def check_all_values(cls, values: dict) -> dict: |
| 38 | + @model_validator(mode="before") |
| 39 | + def check_all_values(cls, data: dict) -> dict: |
38 | 40 | # More about these restrictions: https://jsonapi.org/format/#document-top-level
|
39 |
| - if values.get("data") and values.get("errors"): |
| 41 | + if data.get("data") and data.get("errors"): |
40 | 42 | raise ValueError("The members data and errors MUST NOT coexist in the same document.")
|
41 |
| - if values.get("included") and not values.get("data"): |
| 43 | + if data.get("included") and not data.get("data"): |
42 | 44 | raise ValueError(
|
43 | 45 | "If a document does not contain a top-level data key, the included member MUST NOT be present either."
|
44 | 46 | )
|
45 |
| - if not values.get("data") and not values.get("errors") and not values.get("meta"): |
| 47 | + if not data.get("data") and not data.get("errors") and not data.get("meta"): |
46 | 48 | raise ValueError(
|
47 | 49 | "A document MUST contain at least one of the following top-level members: data, errors, meta."
|
48 | 50 | )
|
49 |
| - return values |
| 51 | + return data |
50 | 52 |
|
51 | 53 |
|
52 | 54 | __all__ = ["TopLevel"]
|
0 commit comments