Skip to content

APIModel

sensei.APIModel

Bases: _ModelBase

Base class used to define models for structuring API responses. There is the OOP style of making Sensei models when an APIModel class performs both validation and making requests through its routed methods. This style is called Routed Model. To use this style, you need to implement a model derived from APIModel and add inside routed methods.

You can apply the same techniques as for pydantic.BaseModel

Import it directly from Sensei:

from sensei import APIModel

Example

from typing import Annotated, Any
from sensei import Router, Path, APIModel

router = Router('https://example.com/api')

class User(APIModel):
     email: str
     id: int
     first_name: str
     last_name: str
     avatar: str

@router.get('/users/{id_}')
def get_user(id_: Annotated[int, Path()]) -> User:
    pass

user = get_user(1)
print(user.email)
from typing import Annotated, Any
from sensei import Router, Path, APIModel

router = Router('https://example.com/api')

class User(APIModel):
     email: str
     id: int
     first_name: str
     last_name: str
     avatar: str

     @classmethod
     @router.get('/users/{id_}')
     def get(cls, id_: Annotated[int, Path()]) -> "User":
         pass

user = User.get(1)
print(user.email)

__finalize_json__ staticmethod

__finalize_json__(json)

Hook used to finalize the JSON response. It's applied for each routed method, associated with the model The final value must be JSON serializable. Can be represented as async function.

JSON finalizer is used for JSON response transformation before internal or user-defined response finalizing.

Example
from sensei import Router, APIModel, Path
from typing import Any, Annotated


router = Router('https://reqres.in/api')


class User(APIModel):
    email: str
    id: int
    first_name: str
    last_name: str
    avatar: str

    @staticmethod
    def __finalize_json__(json: dict[str, Any]) -> dict[str, Any]:
        return json['data']

    @classmethod
    @router.get('/users/{id_}')
    def get(cls, id_: Annotated[int, Path()]) -> "User":
        pass
PARAMETER DESCRIPTION
json

The original JSON response.

TYPE: Json

RETURNS DESCRIPTION
Json

The finalized JSON response.

TYPE: Json

Source code in sensei/_internal/_core/api_model.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
@staticmethod
def __finalize_json__(json: Json) -> Json:
    """
    Hook used to finalize the JSON response. It's applied for each routed method, associated with the model
    The final value must be JSON serializable. Can be represented as **async function**.

    JSON finalizer is used for JSON response transformation before internal or user-defined response finalizing.

    Example:
        ```python
        from sensei import Router, APIModel, Path
        from typing import Any, Annotated


        router = Router('https://reqres.in/api')


        class User(APIModel):
            email: str
            id: int
            first_name: str
            last_name: str
            avatar: str

            @staticmethod
            def __finalize_json__(json: dict[str, Any]) -> dict[str, Any]:
                return json['data']

            @classmethod
            @router.get('/users/{id_}')
            def get(cls, id_: Annotated[int, Path()]) -> "User":
                pass
        ```

    Args:
        json (Json): The original JSON response.

    Returns:
        Json: The finalized JSON response.
    """
    return json

__prepare_args__ staticmethod

__prepare_args__(args)

Hook used to prepare the arguments for the request before it is sent. It's applied for each routed method, associated with the model. The final value must be an instance of Args. Can be represented as async function.

Preparer is executed after internal argument parsing. So, all request parameters are available in Args model within a preparer.

Example
from sensei import APIModel, Router, Args, Path

class Context:
    token: str

router = Router('https://api.example.com')


class User(APIModel):
    email: str
    id: int
    first_name: str
    last_name: str
    avatar: str

    @staticmethod
    def __prepare_args__(args: Args) -> Args:
        args.headers['Authorization'] = f'Bearer {Context.token}'
        return args

    @classmethod
    @router.get('/users/{id_}')
    def get(cls, id_: Annotated[int, Path()]) -> "User":
        pass
PARAMETER DESCRIPTION
args

The original arguments.

TYPE: Args

RETURNS DESCRIPTION
Args

The prepared arguments.

TYPE: Args

Source code in sensei/_internal/_core/api_model.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
@staticmethod
def __prepare_args__(args: Args) -> Args:
    """
    Hook used to prepare the arguments for the request before it is sent. It's applied for
    each routed method, associated with the model. The final value must be an instance of `Args`.
    Can be represented as **async function**.

    Preparer is executed after internal argument parsing. So, all request parameters are available in
    `Args` model within a preparer.

    Example:
        ```python
        from sensei import APIModel, Router, Args, Path

        class Context:
            token: str

        router = Router('https://api.example.com')


        class User(APIModel):
            email: str
            id: int
            first_name: str
            last_name: str
            avatar: str

            @staticmethod
            def __prepare_args__(args: Args) -> Args:
                args.headers['Authorization'] = f'Bearer {Context.token}'
                return args

            @classmethod
            @router.get('/users/{id_}')
            def get(cls, id_: Annotated[int, Path()]) -> "User":
                pass
        ```

    Args:
        args (Args): The original arguments.

    Returns:
        Args: The prepared arguments.
    """
    return args

__default_case__ staticmethod

__default_case__(s)

Hook used to convert the case of all parameters.

PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
141
142
143
144
145
146
147
148
149
150
151
152
@staticmethod
def __default_case__(s: str) -> str:
    """
    Hook used to convert the case of all parameters.

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s

__query_case__ staticmethod

__query_case__(s)

Hook used to convert the case of query parameters.

Example
from sensei import Router, APIModel, Path, camel_case
from typing import Any, Annotated


router = Router('https://reqres.in/api')


class User(APIModel):
    email: str
    id: int
    first_name: str
    last_name: str
    avatar: str

    @staticmethod
    def __query_case__(s: str) -> str:
        return camel_case(s)

    @classmethod
    @router.get('/users/{id_}')
    def get(cls, id_: Annotated[int, Path()]) -> "User":
        pass
PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
@staticmethod
def __query_case__(s: str) -> str:
    """
    Hook used to convert the case of query parameters.

    Example:
        ```python
        from sensei import Router, APIModel, Path, camel_case
        from typing import Any, Annotated


        router = Router('https://reqres.in/api')


        class User(APIModel):
            email: str
            id: int
            first_name: str
            last_name: str
            avatar: str

            @staticmethod
            def __query_case__(s: str) -> str:
                return camel_case(s)

            @classmethod
            @router.get('/users/{id_}')
            def get(cls, id_: Annotated[int, Path()]) -> "User":
                pass
        ```

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s

__body_case__ staticmethod

__body_case__(s)

Hook used to convert the case of body.

PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
193
194
195
196
197
198
199
200
201
202
203
204
@staticmethod
def __body_case__(s: str) -> str:
    """
    Hook used to convert the case of body.

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s
__cookie_case__(s)

Hook used to convert the case of cookies.

PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
206
207
208
209
210
211
212
213
214
215
216
217
@staticmethod
def __cookie_case__(s: str) -> str:
    """
    Hook used to convert the case of cookies.

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s

__header_case__ staticmethod

__header_case__(s)

Hook used to convert the case of headers.

PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
219
220
221
222
223
224
225
226
227
228
229
230
@staticmethod
def __header_case__(s: str) -> str:
    """
    Hook used to convert the case of headers.

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s

__response_case__ staticmethod

__response_case__(s)

Hook used to convert the case of JSON response keys.

PARAMETER DESCRIPTION
s

The original string.

TYPE: str

RETURNS DESCRIPTION
str

The converted string.

TYPE: str

Source code in sensei/_internal/_core/api_model.py
232
233
234
235
236
237
238
239
240
241
242
243
@staticmethod
def __response_case__(s: str) -> str:
    """
    Hook used to convert the case of JSON response keys.

    Args:
        s (str): The original string.

    Returns:
        str: The converted string.
    """
    return s

__str__

__str__()

Get the string representation of the model. Wraps pydantic representation through the class name and parenthesis.

Example
@router.get('/pokemon/{name}')
def get_pokemon(name: Annotated[str, Path(max_length=300)]) -> Pokemon:
    pass


pokemon = get_pokemon(name="pikachu")
print(pokemon)
Pokemon(name='pikachu' id=25 height=4 weight=60)
RETURNS DESCRIPTION
str

String representation of the model

Source code in sensei/_internal/_core/api_model.py
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
def __str__(self):
    """
    Get the string representation of the model. Wraps `pydantic` representation through the class name and
    parenthesis.

    Example:
        ```python
        @router.get('/pokemon/{name}')
        def get_pokemon(name: Annotated[str, Path(max_length=300)]) -> Pokemon:
            pass


        pokemon = get_pokemon(name="pikachu")
        print(pokemon)
        ```

        ```text
        Pokemon(name='pikachu' id=25 height=4 weight=60)
        ```


    Returns:
        str: String representation of the model
    """
    return f'{self.__class__.__name__}({super().__str__()})'