|
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