Coverage for packages/kwai-core/src/kwai_core/json_api.py: 95%

39 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2024-01-01 00:00 +0000

1"""Module that defines some JSON:API related models.""" 

2 

3from fastapi import Query 

4from pydantic import ( 

5 BaseModel, 

6 ConfigDict, 

7 Field, 

8 field_serializer, 

9) 

10 

11 

12class ResourceIdentifier(BaseModel): 

13 """A JSON:API resource identifier.""" 

14 

15 id: str | None = None 

16 type: str 

17 

18 def __hash__(self) -> int: 

19 """Create a hash for a resource.""" 

20 return hash(str(self.id) + self.type) 

21 

22 @field_serializer("id") 

23 def serialize_id(self, id_: str | None, _info): 

24 """When id is serialized, check that it is not None.""" 

25 if id_ is None: 

26 raise ValueError("id should not be None when resource is serialized") 

27 return id_ 

28 

29 

30class Relationship[R](BaseModel): 

31 """A JSON:API relationship.""" 

32 

33 data: R | None = None 

34 

35 

36class RelationshipList[R](BaseModel): 

37 """A JSON:API relationship that is a list.""" 

38 

39 data: list[R] = Field(default_factory=list) 

40 

41 

42class ResourceMeta(BaseModel): 

43 """Meta for a JSON:API resource.""" 

44 

45 model_config = ConfigDict(extra="allow") 

46 

47 created_at: str 

48 updated_at: str | None = None 

49 

50 

51class Meta(BaseModel): 

52 """Defines the metadata for the document model. 

53 

54 Attributes: 

55 count: The number of actual resources 

56 offset: The offset of the returned resources (pagination) 

57 limit: The maximum number of returned resources (pagination) 

58 

59 A limit of 0, means there was no limit set. 

60 """ 

61 

62 model_config = ConfigDict(extra="allow") 

63 

64 count: int = 0 

65 offset: int = 0 

66 limit: int = 0 

67 

68 

69class ErrorSource(BaseModel): 

70 """Defines the model for an error source.""" 

71 

72 pointer: str 

73 

74 

75class Error(BaseModel): 

76 """Defines the model for a JSON:API error.""" 

77 

78 status: str = "" 

79 source: ErrorSource | None = None 

80 title: str = "" 

81 detail: str = "" 

82 

83 

84class PaginationModel(BaseModel): 

85 """A model for pagination query parameters. 

86 

87 Use this as a dependency on a route. This will handle the page[offset] 

88 and page[limit] query parameters. 

89 

90 Attributes: 

91 offset: The value of the page[offset] query parameter. Default is None. 

92 limit: The value of the page[limit] query parameter. Default is None. 

93 """ 

94 

95 offset: int = Field(Query(default=0, alias="page[offset]")) 

96 limit: int = Field(Query(default=0, alias="page[limit]")) 

97 

98 

99class JsonApiPresenter[D]: 

100 """An interface for a presenter that generates a JSON:API document.""" 

101 

102 def __init__(self) -> None: 

103 self._document: D | None = None 

104 

105 def get_document(self) -> D: 

106 """Return the JSON:API document.""" 

107 if self._document is None: 

108 raise ValueError("There is no document created.") 

109 return self._document