apexdevkit 1.5.23__tar.gz → 1.5.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/PKG-INFO +1 -1
- apexdevkit-1.5.25/apexdevkit/fastapi/resource.py +129 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/router.py +49 -44
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/httpx.py +13 -10
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/testing/rest.py +87 -53
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/pyproject.toml +1 -1
- apexdevkit-1.5.23/apexdevkit/fastapi/resource.py +0 -342
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/LICENSE +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/README.md +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/error.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.5.23 → apexdevkit-1.5.25}/apexdevkit/testing/fake.py +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from functools import cached_property
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
from starlette.responses import JSONResponse
|
|
6
|
+
|
|
7
|
+
from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
|
|
8
|
+
from apexdevkit.fastapi.response import RestfulResponse
|
|
9
|
+
from apexdevkit.testing import RestfulName
|
|
10
|
+
|
|
11
|
+
_Response = JSONResponse | dict[str, Any]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class RestfulResource:
|
|
16
|
+
name: RestfulName
|
|
17
|
+
|
|
18
|
+
@cached_property
|
|
19
|
+
def response(self) -> RestfulResponse:
|
|
20
|
+
return RestfulResponse(name=self.name)
|
|
21
|
+
|
|
22
|
+
def create_one(self, Service, Item) -> Callable[..., _Response]: # type: ignore
|
|
23
|
+
def endpoint(service: Service, item: Item) -> _Response:
|
|
24
|
+
try:
|
|
25
|
+
item = service.create_one(item)
|
|
26
|
+
except ExistsError as e:
|
|
27
|
+
return JSONResponse(self.response.exists(e), 409)
|
|
28
|
+
except ForbiddenError as e:
|
|
29
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
30
|
+
|
|
31
|
+
return self.response.created_one(item)
|
|
32
|
+
|
|
33
|
+
return endpoint
|
|
34
|
+
|
|
35
|
+
def create_many(self, Service, Collection) -> Callable[..., _Response]: # type: ignore
|
|
36
|
+
def endpoint(service: Service, items: Collection) -> _Response:
|
|
37
|
+
try:
|
|
38
|
+
return self.response.created_many(service.create_many(items))
|
|
39
|
+
except ExistsError as e:
|
|
40
|
+
return JSONResponse(self.response.exists(e), 409)
|
|
41
|
+
except ForbiddenError as e:
|
|
42
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
43
|
+
|
|
44
|
+
return endpoint
|
|
45
|
+
|
|
46
|
+
def read_one(self, Service, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
47
|
+
def endpoint(service: Service, item_id: ItemId) -> _Response:
|
|
48
|
+
try:
|
|
49
|
+
return self.response.found_one(service.read_one(item_id))
|
|
50
|
+
except DoesNotExistError as e:
|
|
51
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
52
|
+
except ForbiddenError as e:
|
|
53
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
54
|
+
|
|
55
|
+
return endpoint
|
|
56
|
+
|
|
57
|
+
def read_all(self, Service) -> Callable[..., _Response]: # type: ignore
|
|
58
|
+
def endpoint(service: Service) -> _Response:
|
|
59
|
+
try:
|
|
60
|
+
return self.response.found_many(list(service.read_all()))
|
|
61
|
+
except ForbiddenError as e:
|
|
62
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
63
|
+
|
|
64
|
+
return endpoint
|
|
65
|
+
|
|
66
|
+
def update_one(self, Service, ItemId, Updates) -> Callable[..., _Response]: # type: ignore
|
|
67
|
+
def endpoint(service: Service, item_id: ItemId, updates: Updates) -> _Response:
|
|
68
|
+
try:
|
|
69
|
+
service.update_one(item_id, **updates)
|
|
70
|
+
except DoesNotExistError as e:
|
|
71
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
72
|
+
except ForbiddenError as e:
|
|
73
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
74
|
+
|
|
75
|
+
return self.response.ok()
|
|
76
|
+
|
|
77
|
+
return endpoint
|
|
78
|
+
|
|
79
|
+
def update_many(self, Service, Collection) -> Callable[..., _Response]: # type: ignore
|
|
80
|
+
def endpoint(service: Service, items: Collection) -> _Response:
|
|
81
|
+
try:
|
|
82
|
+
service.update_many(items)
|
|
83
|
+
except DoesNotExistError as e:
|
|
84
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
85
|
+
except ForbiddenError as e:
|
|
86
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
87
|
+
|
|
88
|
+
return self.response.ok()
|
|
89
|
+
|
|
90
|
+
return endpoint
|
|
91
|
+
|
|
92
|
+
def replace_one(self, Service, Item) -> Callable[..., _Response]: # type: ignore
|
|
93
|
+
def endpoint(service: Service, item: Item) -> _Response:
|
|
94
|
+
try:
|
|
95
|
+
service.replace_one(item)
|
|
96
|
+
except DoesNotExistError as e:
|
|
97
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
98
|
+
except ForbiddenError as e:
|
|
99
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
100
|
+
|
|
101
|
+
return self.response.ok()
|
|
102
|
+
|
|
103
|
+
return endpoint
|
|
104
|
+
|
|
105
|
+
def replace_many(self, Service, Collection) -> Callable[..., _Response]: # type: ignore
|
|
106
|
+
def endpoint(service: Service, items: Collection) -> _Response:
|
|
107
|
+
try:
|
|
108
|
+
service.replace_many(items)
|
|
109
|
+
except DoesNotExistError as e:
|
|
110
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
111
|
+
except ForbiddenError as e:
|
|
112
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
113
|
+
|
|
114
|
+
return self.response.ok()
|
|
115
|
+
|
|
116
|
+
return endpoint
|
|
117
|
+
|
|
118
|
+
def delete_one(self, Service, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
119
|
+
def endpoint(service: Service, item_id: ItemId) -> _Response:
|
|
120
|
+
try:
|
|
121
|
+
service.delete_one(item_id)
|
|
122
|
+
except DoesNotExistError as e:
|
|
123
|
+
return JSONResponse(self.response.not_found(e), 404)
|
|
124
|
+
except ForbiddenError as e:
|
|
125
|
+
return JSONResponse(self.response.forbidden(e), 403)
|
|
126
|
+
|
|
127
|
+
return self.response.ok()
|
|
128
|
+
|
|
129
|
+
return endpoint
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
2
|
from functools import cached_property
|
|
3
|
-
from typing import Annotated, Any, Callable, Self, TypeVar
|
|
3
|
+
from typing import Annotated, Any, Callable, Self, Type, TypeVar
|
|
4
4
|
|
|
5
|
-
from fastapi import APIRouter, Depends, Path
|
|
5
|
+
from fastapi import APIRouter, Depends, HTTPException, Path
|
|
6
6
|
from fastapi.responses import JSONResponse
|
|
7
7
|
|
|
8
|
+
from apexdevkit.error import DoesNotExistError
|
|
8
9
|
from apexdevkit.fastapi.builder import RestfulServiceBuilder
|
|
9
|
-
from apexdevkit.fastapi.resource import
|
|
10
|
+
from apexdevkit.fastapi.resource import RestfulResource
|
|
11
|
+
from apexdevkit.fastapi.response import RestfulResponse
|
|
10
12
|
from apexdevkit.fastapi.schema import RestfulSchema, SchemaFields
|
|
11
13
|
from apexdevkit.fastapi.service import RawCollection, RawItem, RestfulService
|
|
12
14
|
from apexdevkit.testing import RestfulName
|
|
@@ -50,16 +52,17 @@ class RestfulRouter:
|
|
|
50
52
|
return RestfulSchema(name=self.name, fields=self.fields)
|
|
51
53
|
|
|
52
54
|
@property
|
|
53
|
-
def resource(self) ->
|
|
54
|
-
|
|
55
|
-
return RestfulRootResource(self.name, self.infra)
|
|
56
|
-
|
|
57
|
-
return RestfulSubResource(self.name, self.infra, RestfulName(self.parent))
|
|
55
|
+
def resource(self) -> RestfulResource:
|
|
56
|
+
return RestfulResource(self.name)
|
|
58
57
|
|
|
59
58
|
@property
|
|
60
59
|
def id_alias(self) -> str:
|
|
61
60
|
return self.name.singular + "_id"
|
|
62
61
|
|
|
62
|
+
@property
|
|
63
|
+
def parent_id_alias(self) -> str:
|
|
64
|
+
return self.parent + "_id"
|
|
65
|
+
|
|
63
66
|
@property
|
|
64
67
|
def item_path(self) -> str:
|
|
65
68
|
return "/{" + self.id_alias + "}"
|
|
@@ -92,10 +95,7 @@ class RestfulRouter:
|
|
|
92
95
|
self.router.add_api_route(
|
|
93
96
|
"",
|
|
94
97
|
self.resource.create_one(
|
|
95
|
-
|
|
96
|
-
Any,
|
|
97
|
-
Depends(extract_user),
|
|
98
|
-
],
|
|
98
|
+
Service=self._service(extract_user),
|
|
99
99
|
Item=Annotated[
|
|
100
100
|
RawItem,
|
|
101
101
|
Depends(self.schema.for_create_one()),
|
|
@@ -119,10 +119,7 @@ class RestfulRouter:
|
|
|
119
119
|
self.router.add_api_route(
|
|
120
120
|
"/batch",
|
|
121
121
|
self.resource.create_many(
|
|
122
|
-
|
|
123
|
-
Any,
|
|
124
|
-
Depends(extract_user),
|
|
125
|
-
],
|
|
122
|
+
Service=self._service(extract_user),
|
|
126
123
|
Collection=Annotated[
|
|
127
124
|
RawCollection,
|
|
128
125
|
Depends(self.schema.for_create_many()),
|
|
@@ -146,10 +143,7 @@ class RestfulRouter:
|
|
|
146
143
|
self.router.add_api_route(
|
|
147
144
|
self.item_path,
|
|
148
145
|
self.resource.read_one(
|
|
149
|
-
|
|
150
|
-
Any,
|
|
151
|
-
Depends(extract_user),
|
|
152
|
-
],
|
|
146
|
+
Service=self._service(extract_user),
|
|
153
147
|
ItemId=Annotated[
|
|
154
148
|
str,
|
|
155
149
|
Path(alias=self.id_alias),
|
|
@@ -173,10 +167,7 @@ class RestfulRouter:
|
|
|
173
167
|
self.router.add_api_route(
|
|
174
168
|
"",
|
|
175
169
|
self.resource.read_all(
|
|
176
|
-
|
|
177
|
-
Any,
|
|
178
|
-
Depends(extract_user),
|
|
179
|
-
],
|
|
170
|
+
Service=self._service(extract_user),
|
|
180
171
|
),
|
|
181
172
|
methods=["GET"],
|
|
182
173
|
status_code=200,
|
|
@@ -196,10 +187,7 @@ class RestfulRouter:
|
|
|
196
187
|
self.router.add_api_route(
|
|
197
188
|
self.item_path,
|
|
198
189
|
self.resource.update_one(
|
|
199
|
-
|
|
200
|
-
Any,
|
|
201
|
-
Depends(extract_user),
|
|
202
|
-
],
|
|
190
|
+
Service=self._service(extract_user),
|
|
203
191
|
ItemId=Annotated[
|
|
204
192
|
str,
|
|
205
193
|
Path(alias=self.id_alias),
|
|
@@ -227,10 +215,7 @@ class RestfulRouter:
|
|
|
227
215
|
self.router.add_api_route(
|
|
228
216
|
"",
|
|
229
217
|
self.resource.update_many(
|
|
230
|
-
|
|
231
|
-
Any,
|
|
232
|
-
Depends(extract_user),
|
|
233
|
-
],
|
|
218
|
+
Service=self._service(extract_user),
|
|
234
219
|
Collection=Annotated[
|
|
235
220
|
RawCollection,
|
|
236
221
|
Depends(self.schema.for_update_many()),
|
|
@@ -254,10 +239,7 @@ class RestfulRouter:
|
|
|
254
239
|
self.router.add_api_route(
|
|
255
240
|
"",
|
|
256
241
|
self.resource.replace_one(
|
|
257
|
-
|
|
258
|
-
Any,
|
|
259
|
-
Depends(extract_user),
|
|
260
|
-
],
|
|
242
|
+
Service=self._service(extract_user),
|
|
261
243
|
Item=Annotated[
|
|
262
244
|
RawItem,
|
|
263
245
|
Depends(self.schema.for_replace_one()),
|
|
@@ -281,10 +263,7 @@ class RestfulRouter:
|
|
|
281
263
|
self.router.add_api_route(
|
|
282
264
|
"/batch",
|
|
283
265
|
self.resource.replace_many(
|
|
284
|
-
|
|
285
|
-
Any,
|
|
286
|
-
Depends(extract_user),
|
|
287
|
-
],
|
|
266
|
+
Service=self._service(extract_user),
|
|
288
267
|
Collection=Annotated[
|
|
289
268
|
RawCollection,
|
|
290
269
|
Depends(self.schema.for_replace_many()),
|
|
@@ -308,10 +287,7 @@ class RestfulRouter:
|
|
|
308
287
|
self.router.add_api_route(
|
|
309
288
|
self.item_path,
|
|
310
289
|
self.resource.delete_one(
|
|
311
|
-
|
|
312
|
-
Any,
|
|
313
|
-
Depends(extract_user),
|
|
314
|
-
],
|
|
290
|
+
Service=self._service(extract_user),
|
|
315
291
|
ItemId=Annotated[
|
|
316
292
|
str,
|
|
317
293
|
Path(alias=self.id_alias),
|
|
@@ -346,3 +322,32 @@ class RestfulRouter:
|
|
|
346
322
|
|
|
347
323
|
def build(self) -> APIRouter:
|
|
348
324
|
return self.router
|
|
325
|
+
|
|
326
|
+
def _service(
|
|
327
|
+
self, extract_user: Callable[..., Any] = no_user
|
|
328
|
+
) -> Type[RestfulService]:
|
|
329
|
+
User = Annotated[Any, Depends(extract_user)]
|
|
330
|
+
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
331
|
+
|
|
332
|
+
def srv_child(user: User, parent_id: ParentId) -> RestfulService:
|
|
333
|
+
try:
|
|
334
|
+
return self.infra.with_user(user).with_parent(parent_id).build()
|
|
335
|
+
except DoesNotExistError as e:
|
|
336
|
+
raise HTTPException(
|
|
337
|
+
status_code=404,
|
|
338
|
+
detail=RestfulResponse(RestfulName(self.parent)).not_found(e),
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
def srv_root(user: User) -> RestfulService:
|
|
342
|
+
try:
|
|
343
|
+
return self.infra.with_user(user).build()
|
|
344
|
+
except DoesNotExistError as e:
|
|
345
|
+
raise HTTPException(
|
|
346
|
+
status_code=404,
|
|
347
|
+
detail=RestfulResponse(RestfulName(self.parent)).not_found(e),
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
if self.parent:
|
|
351
|
+
return Annotated[RestfulService, Depends(srv_child)] # type: ignore
|
|
352
|
+
else:
|
|
353
|
+
return Annotated[RestfulService, Depends(srv_root)] # type: ignore
|
|
@@ -4,34 +4,37 @@ from dataclasses import dataclass, field
|
|
|
4
4
|
from typing import Any, Iterator, Mapping, Self
|
|
5
5
|
|
|
6
6
|
import httpx
|
|
7
|
+
from httpx import Client
|
|
7
8
|
|
|
8
9
|
from apexdevkit.http.fluent import HttpMethod, HttpResponse
|
|
9
10
|
from apexdevkit.http.json import JsonDict
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def default_config() -> HttpxConfig:
|
|
14
|
+
return HttpxConfig()
|
|
11
15
|
|
|
12
16
|
|
|
13
17
|
@dataclass(frozen=True)
|
|
14
18
|
class Httpx:
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
client: httpx.Client
|
|
20
|
+
|
|
21
|
+
config: HttpxConfig = field(default_factory=default_config)
|
|
17
22
|
|
|
18
23
|
@classmethod
|
|
19
24
|
def create_for(cls, url: str) -> Self:
|
|
20
|
-
return cls(
|
|
25
|
+
return cls(Client(base_url=url), HttpxConfig())
|
|
21
26
|
|
|
22
27
|
def with_header(self, key: str, value: str) -> Httpx:
|
|
23
|
-
return Httpx(self.
|
|
28
|
+
return Httpx(self.client, self.config.with_header(key, value))
|
|
24
29
|
|
|
25
30
|
def with_param(self, key: str, value: str) -> Httpx:
|
|
26
|
-
return Httpx(self.
|
|
31
|
+
return Httpx(self.client, self.config.with_param(key, value))
|
|
27
32
|
|
|
28
33
|
def with_json(self, value: JsonDict) -> Httpx:
|
|
29
|
-
return Httpx(self.
|
|
34
|
+
return Httpx(self.client, self.config.with_json(value))
|
|
30
35
|
|
|
31
36
|
def request(self, method: HttpMethod, endpoint: str) -> HttpResponse:
|
|
32
|
-
return _HttpxResponse(
|
|
33
|
-
httpx.request(method.name, self.url + endpoint, **self.config)
|
|
34
|
-
)
|
|
37
|
+
return _HttpxResponse(self.client.request(method.name, endpoint, **self.config))
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
@dataclass
|
|
@@ -5,67 +5,76 @@ from dataclasses import dataclass, field
|
|
|
5
5
|
from functools import cached_property
|
|
6
6
|
from typing import Any, Iterable, Self
|
|
7
7
|
|
|
8
|
-
import httpx
|
|
9
8
|
from fastapi.testclient import TestClient
|
|
10
9
|
|
|
11
|
-
from apexdevkit.http import HttpUrl, JsonDict
|
|
10
|
+
from apexdevkit.http import Http, HttpUrl, JsonDict
|
|
11
|
+
from apexdevkit.http.fluent import HttpMethod, HttpResponse
|
|
12
|
+
from apexdevkit.http.httpx import Httpx
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
@dataclass
|
|
15
16
|
class RestResource:
|
|
16
|
-
http: TestClient
|
|
17
|
+
http: TestClient | Http
|
|
17
18
|
name: RestfulName
|
|
18
19
|
|
|
20
|
+
def __post_init__(self) -> None:
|
|
21
|
+
if isinstance(self.http, TestClient):
|
|
22
|
+
self.http = Httpx(self.http)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def _http(self) -> Http:
|
|
26
|
+
assert not isinstance(self.http, TestClient)
|
|
27
|
+
|
|
28
|
+
return self.http
|
|
29
|
+
|
|
19
30
|
def create_one(self) -> CreateOne:
|
|
20
|
-
return CreateOne(self.name, self.
|
|
31
|
+
return CreateOne(self.name, self._http)
|
|
21
32
|
|
|
22
33
|
def create_many(self) -> CreateMany:
|
|
23
|
-
return CreateMany(self.name, self.
|
|
34
|
+
return CreateMany(self.name, self._http)
|
|
24
35
|
|
|
25
36
|
def read_one(self) -> ReadOne:
|
|
26
|
-
return ReadOne(self.name, self.
|
|
37
|
+
return ReadOne(self.name, self._http)
|
|
27
38
|
|
|
28
39
|
def read_all(self) -> ReadAll:
|
|
29
|
-
return ReadAll(self.name, self.
|
|
40
|
+
return ReadAll(self.name, self._http)
|
|
30
41
|
|
|
31
42
|
def update_one(self) -> UpdateOne:
|
|
32
|
-
return UpdateOne(self.name, self.
|
|
43
|
+
return UpdateOne(self.name, self._http)
|
|
33
44
|
|
|
34
45
|
def update_many(self) -> UpdateMany:
|
|
35
|
-
return UpdateMany(self.name, self.
|
|
46
|
+
return UpdateMany(self.name, self._http)
|
|
36
47
|
|
|
37
48
|
def replace_one(self) -> ReplaceOne:
|
|
38
|
-
return ReplaceOne(self.name, self.
|
|
49
|
+
return ReplaceOne(self.name, self._http)
|
|
39
50
|
|
|
40
51
|
def replace_many(self) -> ReplaceMany:
|
|
41
|
-
return ReplaceMany(self.name, self.
|
|
52
|
+
return ReplaceMany(self.name, self._http)
|
|
42
53
|
|
|
43
54
|
def delete_one(self) -> DeleteOne:
|
|
44
|
-
return DeleteOne(self.name, self.
|
|
55
|
+
return DeleteOne(self.name, self._http)
|
|
45
56
|
|
|
46
57
|
|
|
47
58
|
@dataclass
|
|
48
59
|
class RestCollection(RestResource):
|
|
49
60
|
def sub_resource(self, name: str) -> RestItem:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)
|
|
61
|
+
assert isinstance(self.http, Httpx), "sub resource only works with Httpx"
|
|
62
|
+
|
|
63
|
+
client = self.http.client
|
|
64
|
+
client.base_url = client.base_url.join(self.name.plural)
|
|
65
|
+
|
|
66
|
+
return RestItem(self.http, RestfulName(name))
|
|
57
67
|
|
|
58
68
|
|
|
59
69
|
@dataclass
|
|
60
70
|
class RestItem(RestResource):
|
|
61
71
|
def sub_resource(self, name: str) -> RestItem:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
72
|
+
assert isinstance(self.http, Httpx), "sub resource only works with Httpx"
|
|
73
|
+
|
|
74
|
+
client = self.http.client
|
|
75
|
+
client.base_url = client.base_url.join(self.name.plural)
|
|
76
|
+
|
|
77
|
+
return RestItem(self.http, RestfulName(name))
|
|
69
78
|
|
|
70
79
|
|
|
71
80
|
@dataclass
|
|
@@ -103,11 +112,11 @@ def as_plural(singular: str) -> str:
|
|
|
103
112
|
@dataclass
|
|
104
113
|
class RestRequest:
|
|
105
114
|
resource: RestfulName
|
|
106
|
-
http:
|
|
115
|
+
http: Http
|
|
107
116
|
|
|
108
117
|
@abstractmethod
|
|
109
118
|
@cached_property
|
|
110
|
-
def response(self) ->
|
|
119
|
+
def response(self) -> HttpResponse: # pragma: no cover
|
|
111
120
|
pass
|
|
112
121
|
|
|
113
122
|
def unpack(self) -> JsonDict:
|
|
@@ -122,7 +131,7 @@ class RestRequest:
|
|
|
122
131
|
return RestResponse(
|
|
123
132
|
resource=self.resource,
|
|
124
133
|
json=JsonDict(self.response.json()),
|
|
125
|
-
http_code=self.response.
|
|
134
|
+
http_code=self.response.code(),
|
|
126
135
|
)
|
|
127
136
|
|
|
128
137
|
|
|
@@ -136,8 +145,11 @@ class CreateOne(RestRequest):
|
|
|
136
145
|
return self
|
|
137
146
|
|
|
138
147
|
@cached_property
|
|
139
|
-
def response(self) ->
|
|
140
|
-
return self.http.
|
|
148
|
+
def response(self) -> HttpResponse:
|
|
149
|
+
return self.http.with_json(self.data).request(
|
|
150
|
+
method=HttpMethod.post,
|
|
151
|
+
endpoint=self.resource + "",
|
|
152
|
+
)
|
|
141
153
|
|
|
142
154
|
|
|
143
155
|
@dataclass
|
|
@@ -145,8 +157,11 @@ class ReadOne(RestRequest):
|
|
|
145
157
|
item_id: str = field(init=False)
|
|
146
158
|
|
|
147
159
|
@cached_property
|
|
148
|
-
def response(self) ->
|
|
149
|
-
return self.http.
|
|
160
|
+
def response(self) -> HttpResponse:
|
|
161
|
+
return self.http.request(
|
|
162
|
+
method=HttpMethod.get,
|
|
163
|
+
endpoint=self.resource + str(self.item_id),
|
|
164
|
+
)
|
|
150
165
|
|
|
151
166
|
def with_id(self, value: Any) -> Self:
|
|
152
167
|
self.item_id = str(value)
|
|
@@ -159,8 +174,12 @@ class ReadAll(RestRequest):
|
|
|
159
174
|
params: dict[str, Any] = field(init=False, default_factory=dict)
|
|
160
175
|
|
|
161
176
|
@cached_property
|
|
162
|
-
def response(self) ->
|
|
163
|
-
|
|
177
|
+
def response(self) -> HttpResponse:
|
|
178
|
+
http = self.http
|
|
179
|
+
for param, value in self.params.items():
|
|
180
|
+
http = http.with_param(param, value)
|
|
181
|
+
|
|
182
|
+
return http.request(method=HttpMethod.get, endpoint=self.resource + "")
|
|
164
183
|
|
|
165
184
|
def with_params(self, **kwargs: Any) -> Self:
|
|
166
185
|
self.params = {**kwargs}
|
|
@@ -174,8 +193,11 @@ class UpdateOne(RestRequest):
|
|
|
174
193
|
data: JsonDict = field(init=False)
|
|
175
194
|
|
|
176
195
|
@cached_property
|
|
177
|
-
def response(self) ->
|
|
178
|
-
return self.http.
|
|
196
|
+
def response(self) -> HttpResponse:
|
|
197
|
+
return self.http.with_json(self.data).request(
|
|
198
|
+
method=HttpMethod.patch,
|
|
199
|
+
endpoint=self.resource + str(self.item_id),
|
|
200
|
+
)
|
|
179
201
|
|
|
180
202
|
def with_id(self, value: Any) -> Self:
|
|
181
203
|
self.item_id = str(value)
|
|
@@ -193,8 +215,11 @@ class ReplaceOne(RestRequest):
|
|
|
193
215
|
data: JsonDict = field(init=False)
|
|
194
216
|
|
|
195
217
|
@cached_property
|
|
196
|
-
def response(self) ->
|
|
197
|
-
return self.http.
|
|
218
|
+
def response(self) -> HttpResponse:
|
|
219
|
+
return self.http.with_json(self.data).request(
|
|
220
|
+
method=HttpMethod.put,
|
|
221
|
+
endpoint=self.resource + "",
|
|
222
|
+
)
|
|
198
223
|
|
|
199
224
|
def from_data(self, value: JsonDict) -> Self:
|
|
200
225
|
self.data = value
|
|
@@ -207,10 +232,12 @@ class CreateMany(RestRequest):
|
|
|
207
232
|
data: list[JsonDict] = field(default_factory=list)
|
|
208
233
|
|
|
209
234
|
@cached_property
|
|
210
|
-
def response(self) ->
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
235
|
+
def response(self) -> HttpResponse:
|
|
236
|
+
json = JsonDict({self.resource.plural: [dict(data) for data in self.data]})
|
|
237
|
+
|
|
238
|
+
return self.http.with_json(json).request(
|
|
239
|
+
method=HttpMethod.post,
|
|
240
|
+
endpoint=self.resource + "batch",
|
|
214
241
|
)
|
|
215
242
|
|
|
216
243
|
def from_data(self, value: JsonDict) -> Self:
|
|
@@ -227,10 +254,12 @@ class UpdateMany(RestRequest):
|
|
|
227
254
|
data: list[JsonDict] = field(default_factory=list)
|
|
228
255
|
|
|
229
256
|
@cached_property
|
|
230
|
-
def response(self) ->
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
257
|
+
def response(self) -> HttpResponse:
|
|
258
|
+
json = JsonDict({self.resource.plural: [dict(data) for data in self.data]})
|
|
259
|
+
|
|
260
|
+
return self.http.with_json(json).request(
|
|
261
|
+
method=HttpMethod.patch,
|
|
262
|
+
endpoint=self.resource + "",
|
|
234
263
|
)
|
|
235
264
|
|
|
236
265
|
def from_data(self, value: JsonDict) -> Self:
|
|
@@ -247,10 +276,12 @@ class ReplaceMany(RestRequest):
|
|
|
247
276
|
data: list[JsonDict] = field(default_factory=list)
|
|
248
277
|
|
|
249
278
|
@cached_property
|
|
250
|
-
def response(self) ->
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
279
|
+
def response(self) -> HttpResponse:
|
|
280
|
+
json = JsonDict({self.resource.plural: [dict(data) for data in self.data]})
|
|
281
|
+
|
|
282
|
+
return self.http.with_json(json).request(
|
|
283
|
+
method=HttpMethod.put,
|
|
284
|
+
endpoint=self.resource + "batch",
|
|
254
285
|
)
|
|
255
286
|
|
|
256
287
|
def from_data(self, value: JsonDict) -> Self:
|
|
@@ -267,8 +298,11 @@ class DeleteOne(RestRequest):
|
|
|
267
298
|
item_id: str = field(init=False)
|
|
268
299
|
|
|
269
300
|
@cached_property
|
|
270
|
-
def response(self) ->
|
|
271
|
-
return self.http.
|
|
301
|
+
def response(self) -> HttpResponse:
|
|
302
|
+
return self.http.request(
|
|
303
|
+
method=HttpMethod.delete,
|
|
304
|
+
endpoint=self.resource + str(self.item_id),
|
|
305
|
+
)
|
|
272
306
|
|
|
273
307
|
def with_id(self, value: Any) -> Self:
|
|
274
308
|
self.item_id = str(value)
|
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from functools import cached_property
|
|
3
|
-
from typing import Annotated, Any, Callable
|
|
4
|
-
|
|
5
|
-
from fastapi import Path
|
|
6
|
-
from starlette.responses import JSONResponse
|
|
7
|
-
|
|
8
|
-
from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
|
|
9
|
-
from apexdevkit.fastapi.builder import RestfulServiceBuilder
|
|
10
|
-
from apexdevkit.fastapi.response import RestfulResponse
|
|
11
|
-
from apexdevkit.testing import RestfulName
|
|
12
|
-
|
|
13
|
-
_Response = JSONResponse | dict[str, Any]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass
|
|
17
|
-
class RestfulSubResource:
|
|
18
|
-
name: RestfulName
|
|
19
|
-
infra: RestfulServiceBuilder
|
|
20
|
-
parent: RestfulName
|
|
21
|
-
|
|
22
|
-
@property
|
|
23
|
-
def parent_id_alias(self) -> str:
|
|
24
|
-
return self.parent.singular + "_id"
|
|
25
|
-
|
|
26
|
-
@cached_property
|
|
27
|
-
def response(self) -> RestfulResponse:
|
|
28
|
-
return RestfulResponse(name=self.name)
|
|
29
|
-
|
|
30
|
-
def create_one(self, User, Item) -> Callable[..., _Response]: # type: ignore
|
|
31
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
32
|
-
|
|
33
|
-
def endpoint(user: User, parent_id: ParentId, item: Item) -> _Response:
|
|
34
|
-
try:
|
|
35
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
36
|
-
except DoesNotExistError as e:
|
|
37
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
item = service.create_one(item)
|
|
41
|
-
except ExistsError as e:
|
|
42
|
-
return JSONResponse(self.response.exists(e), 409)
|
|
43
|
-
except ForbiddenError as e:
|
|
44
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
45
|
-
|
|
46
|
-
return self.response.created_one(item)
|
|
47
|
-
|
|
48
|
-
return endpoint
|
|
49
|
-
|
|
50
|
-
def create_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
51
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
52
|
-
|
|
53
|
-
def endpoint(user: User, parent_id: ParentId, items: Collection) -> _Response:
|
|
54
|
-
try:
|
|
55
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
56
|
-
except DoesNotExistError as e:
|
|
57
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
58
|
-
|
|
59
|
-
try:
|
|
60
|
-
return self.response.created_many(service.create_many(items))
|
|
61
|
-
except ExistsError as e:
|
|
62
|
-
return JSONResponse(self.response.exists(e), 409)
|
|
63
|
-
except ForbiddenError as e:
|
|
64
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
65
|
-
|
|
66
|
-
return endpoint
|
|
67
|
-
|
|
68
|
-
def read_one(self, User, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
69
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
70
|
-
|
|
71
|
-
def endpoint(user: User, parent_id: ParentId, item_id: ItemId) -> _Response:
|
|
72
|
-
try:
|
|
73
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
74
|
-
except DoesNotExistError as e:
|
|
75
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
76
|
-
|
|
77
|
-
try:
|
|
78
|
-
return self.response.found_one(service.read_one(item_id))
|
|
79
|
-
except DoesNotExistError as e:
|
|
80
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
81
|
-
except ForbiddenError as e:
|
|
82
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
83
|
-
|
|
84
|
-
return endpoint
|
|
85
|
-
|
|
86
|
-
def read_all(self, User) -> Callable[..., _Response]: # type: ignore
|
|
87
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
88
|
-
|
|
89
|
-
def endpoint(user: User, parent_id: ParentId) -> _Response:
|
|
90
|
-
try:
|
|
91
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
92
|
-
except DoesNotExistError as e:
|
|
93
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
94
|
-
|
|
95
|
-
try:
|
|
96
|
-
return self.response.found_many(list(service.read_all()))
|
|
97
|
-
except ForbiddenError as e:
|
|
98
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
99
|
-
|
|
100
|
-
return endpoint
|
|
101
|
-
|
|
102
|
-
def update_one(self, User, ItemId, Updates) -> Callable[..., _Response]: # type: ignore
|
|
103
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
104
|
-
|
|
105
|
-
def endpoint(
|
|
106
|
-
user: User,
|
|
107
|
-
parent_id: ParentId,
|
|
108
|
-
item_id: ItemId,
|
|
109
|
-
updates: Updates,
|
|
110
|
-
) -> _Response:
|
|
111
|
-
try:
|
|
112
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
113
|
-
except DoesNotExistError as e:
|
|
114
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
115
|
-
|
|
116
|
-
try:
|
|
117
|
-
service.update_one(item_id, **updates)
|
|
118
|
-
except DoesNotExistError as e:
|
|
119
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
120
|
-
except ForbiddenError as e:
|
|
121
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
122
|
-
|
|
123
|
-
return self.response.ok()
|
|
124
|
-
|
|
125
|
-
return endpoint
|
|
126
|
-
|
|
127
|
-
def update_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
128
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
129
|
-
|
|
130
|
-
def endpoint(user: User, parent_id: ParentId, items: Collection) -> _Response:
|
|
131
|
-
try:
|
|
132
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
133
|
-
except DoesNotExistError as e:
|
|
134
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
135
|
-
|
|
136
|
-
try:
|
|
137
|
-
service.update_many(items)
|
|
138
|
-
except DoesNotExistError as e:
|
|
139
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
140
|
-
except ForbiddenError as e:
|
|
141
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
142
|
-
|
|
143
|
-
return self.response.ok()
|
|
144
|
-
|
|
145
|
-
return endpoint
|
|
146
|
-
|
|
147
|
-
def replace_one(self, User, Item) -> Callable[..., _Response]: # type: ignore
|
|
148
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
149
|
-
|
|
150
|
-
def endpoint(user: User, parent_id: ParentId, item: Item) -> _Response:
|
|
151
|
-
try:
|
|
152
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
153
|
-
except DoesNotExistError as e:
|
|
154
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
155
|
-
|
|
156
|
-
try:
|
|
157
|
-
service.replace_one(item)
|
|
158
|
-
except DoesNotExistError as e:
|
|
159
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
160
|
-
except ForbiddenError as e:
|
|
161
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
162
|
-
|
|
163
|
-
return self.response.ok()
|
|
164
|
-
|
|
165
|
-
return endpoint
|
|
166
|
-
|
|
167
|
-
def replace_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
168
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
169
|
-
|
|
170
|
-
def endpoint(user: User, parent_id: ParentId, items: Collection) -> _Response:
|
|
171
|
-
try:
|
|
172
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
173
|
-
except DoesNotExistError as e:
|
|
174
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
175
|
-
|
|
176
|
-
try:
|
|
177
|
-
service.replace_many(items)
|
|
178
|
-
except DoesNotExistError as e:
|
|
179
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
180
|
-
except ForbiddenError as e:
|
|
181
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
182
|
-
|
|
183
|
-
return self.response.ok()
|
|
184
|
-
|
|
185
|
-
return endpoint
|
|
186
|
-
|
|
187
|
-
def delete_one(self, User, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
188
|
-
ParentId = Annotated[str, Path(alias=self.parent_id_alias)]
|
|
189
|
-
|
|
190
|
-
def endpoint(user: User, parent_id: ParentId, item_id: ItemId) -> _Response:
|
|
191
|
-
try:
|
|
192
|
-
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
193
|
-
except DoesNotExistError as e:
|
|
194
|
-
return JSONResponse(RestfulResponse(self.parent).not_found(e), 404)
|
|
195
|
-
|
|
196
|
-
try:
|
|
197
|
-
service.delete_one(item_id)
|
|
198
|
-
except DoesNotExistError as e:
|
|
199
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
200
|
-
except ForbiddenError as e:
|
|
201
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
202
|
-
|
|
203
|
-
return self.response.ok()
|
|
204
|
-
|
|
205
|
-
return endpoint
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
@dataclass
|
|
209
|
-
class RestfulRootResource:
|
|
210
|
-
name: RestfulName
|
|
211
|
-
infra: RestfulServiceBuilder
|
|
212
|
-
|
|
213
|
-
@cached_property
|
|
214
|
-
def response(self) -> RestfulResponse:
|
|
215
|
-
return RestfulResponse(name=self.name)
|
|
216
|
-
|
|
217
|
-
def create_one(self, User, Item) -> Callable[..., _Response]: # type: ignore
|
|
218
|
-
def endpoint(user: User, item: Item) -> _Response:
|
|
219
|
-
service = self.infra.with_user(user).build()
|
|
220
|
-
|
|
221
|
-
try:
|
|
222
|
-
item = service.create_one(item)
|
|
223
|
-
except ExistsError as e:
|
|
224
|
-
return JSONResponse(self.response.exists(e), 409)
|
|
225
|
-
except ForbiddenError as e:
|
|
226
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
227
|
-
|
|
228
|
-
return self.response.created_one(item)
|
|
229
|
-
|
|
230
|
-
return endpoint
|
|
231
|
-
|
|
232
|
-
def create_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
233
|
-
def endpoint(user: User, items: Collection) -> _Response:
|
|
234
|
-
service = self.infra.with_user(user).build()
|
|
235
|
-
|
|
236
|
-
try:
|
|
237
|
-
return self.response.created_many(service.create_many(items))
|
|
238
|
-
except ExistsError as e:
|
|
239
|
-
return JSONResponse(self.response.exists(e), 409)
|
|
240
|
-
except ForbiddenError as e:
|
|
241
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
242
|
-
|
|
243
|
-
return endpoint
|
|
244
|
-
|
|
245
|
-
def read_one(self, User, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
246
|
-
def endpoint(user: User, item_id: ItemId) -> _Response:
|
|
247
|
-
service = self.infra.with_user(user).build()
|
|
248
|
-
|
|
249
|
-
try:
|
|
250
|
-
return self.response.found_one(service.read_one(item_id))
|
|
251
|
-
except DoesNotExistError as e:
|
|
252
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
253
|
-
except ForbiddenError as e:
|
|
254
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
255
|
-
|
|
256
|
-
return endpoint
|
|
257
|
-
|
|
258
|
-
def read_all(self, User) -> Callable[..., _Response]: # type: ignore
|
|
259
|
-
def endpoint(user: User) -> _Response:
|
|
260
|
-
service = self.infra.with_user(user).build()
|
|
261
|
-
|
|
262
|
-
try:
|
|
263
|
-
return self.response.found_many(list(service.read_all()))
|
|
264
|
-
except ForbiddenError as e:
|
|
265
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
266
|
-
|
|
267
|
-
return endpoint
|
|
268
|
-
|
|
269
|
-
def update_one(self, User, ItemId, Updates) -> Callable[..., _Response]: # type: ignore
|
|
270
|
-
def endpoint(user: User, item_id: ItemId, updates: Updates) -> _Response:
|
|
271
|
-
service = self.infra.with_user(user).build()
|
|
272
|
-
|
|
273
|
-
try:
|
|
274
|
-
service.update_one(item_id, **updates)
|
|
275
|
-
except DoesNotExistError as e:
|
|
276
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
277
|
-
except ForbiddenError as e:
|
|
278
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
279
|
-
|
|
280
|
-
return self.response.ok()
|
|
281
|
-
|
|
282
|
-
return endpoint
|
|
283
|
-
|
|
284
|
-
def update_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
285
|
-
def endpoint(user: User, items: Collection) -> _Response:
|
|
286
|
-
service = self.infra.with_user(user).build()
|
|
287
|
-
|
|
288
|
-
try:
|
|
289
|
-
service.update_many(items)
|
|
290
|
-
except DoesNotExistError as e:
|
|
291
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
292
|
-
except ForbiddenError as e:
|
|
293
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
294
|
-
|
|
295
|
-
return self.response.ok()
|
|
296
|
-
|
|
297
|
-
return endpoint
|
|
298
|
-
|
|
299
|
-
def replace_one(self, User, Item) -> Callable[..., _Response]: # type: ignore
|
|
300
|
-
def endpoint(user: User, item: Item) -> _Response:
|
|
301
|
-
service = self.infra.with_user(user).build()
|
|
302
|
-
|
|
303
|
-
try:
|
|
304
|
-
service.replace_one(item)
|
|
305
|
-
except DoesNotExistError as e:
|
|
306
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
307
|
-
except ForbiddenError as e:
|
|
308
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
309
|
-
|
|
310
|
-
return self.response.ok()
|
|
311
|
-
|
|
312
|
-
return endpoint
|
|
313
|
-
|
|
314
|
-
def replace_many(self, User, Collection) -> Callable[..., _Response]: # type: ignore
|
|
315
|
-
def endpoint(user: User, items: Collection) -> _Response:
|
|
316
|
-
service = self.infra.with_user(user).build()
|
|
317
|
-
|
|
318
|
-
try:
|
|
319
|
-
service.replace_many(items)
|
|
320
|
-
except DoesNotExistError as e:
|
|
321
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
322
|
-
except ForbiddenError as e:
|
|
323
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
324
|
-
|
|
325
|
-
return self.response.ok()
|
|
326
|
-
|
|
327
|
-
return endpoint
|
|
328
|
-
|
|
329
|
-
def delete_one(self, User, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
330
|
-
def endpoint(user: User, item_id: ItemId) -> _Response:
|
|
331
|
-
service = self.infra.with_user(user).build()
|
|
332
|
-
|
|
333
|
-
try:
|
|
334
|
-
service.delete_one(item_id)
|
|
335
|
-
except DoesNotExistError as e:
|
|
336
|
-
return JSONResponse(self.response.not_found(e), 404)
|
|
337
|
-
except ForbiddenError as e:
|
|
338
|
-
return JSONResponse(self.response.forbidden(e), 403)
|
|
339
|
-
|
|
340
|
-
return self.response.ok()
|
|
341
|
-
|
|
342
|
-
return endpoint
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|