apexdevkit 1.4.3__tar.gz → 1.4.4__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.4.3 → apexdevkit-1.4.4}/PKG-INFO +1 -1
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/router.py +173 -113
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/pyproject.toml +1 -1
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/LICENSE +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/README.md +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/error.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/repository/in_memory.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.4.3 → apexdevkit-1.4.4}/apexdevkit/testing/rest.py +0 -0
|
@@ -4,7 +4,6 @@ from functools import cached_property
|
|
|
4
4
|
from typing import Annotated, Any, Callable, Iterable, Self, TypeVar
|
|
5
5
|
|
|
6
6
|
from fastapi import APIRouter, Depends, Path
|
|
7
|
-
from fastapi.requests import Request
|
|
8
7
|
from fastapi.responses import JSONResponse
|
|
9
8
|
|
|
10
9
|
from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
|
|
@@ -108,7 +107,7 @@ class PreBuiltRestfulService(RestfulServiceBuilder):
|
|
|
108
107
|
return self.service
|
|
109
108
|
|
|
110
109
|
|
|
111
|
-
def no_user(
|
|
110
|
+
def no_user() -> None:
|
|
112
111
|
pass
|
|
113
112
|
|
|
114
113
|
|
|
@@ -181,30 +180,36 @@ class RestfulRouter:
|
|
|
181
180
|
def with_create_one_endpoint(
|
|
182
181
|
self,
|
|
183
182
|
is_documented: bool = True,
|
|
184
|
-
extract_user: Callable[
|
|
183
|
+
extract_user: Callable[..., Any] = no_user,
|
|
185
184
|
) -> Self:
|
|
186
|
-
|
|
187
|
-
str,
|
|
188
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
189
|
-
]
|
|
190
|
-
|
|
191
|
-
item_type = Annotated[
|
|
192
|
-
RawItem,
|
|
193
|
-
Depends(self.schema.for_create_one()),
|
|
194
|
-
]
|
|
195
|
-
|
|
196
|
-
@self.router.post(
|
|
185
|
+
self.router.add_api_route(
|
|
197
186
|
"",
|
|
187
|
+
self.create_one(
|
|
188
|
+
User=Annotated[
|
|
189
|
+
Any,
|
|
190
|
+
Depends(extract_user),
|
|
191
|
+
],
|
|
192
|
+
ParentId=Annotated[
|
|
193
|
+
str,
|
|
194
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
195
|
+
],
|
|
196
|
+
Item=Annotated[
|
|
197
|
+
RawItem,
|
|
198
|
+
Depends(self.schema.for_create_one()),
|
|
199
|
+
],
|
|
200
|
+
),
|
|
201
|
+
methods=["POST"],
|
|
198
202
|
status_code=201,
|
|
199
203
|
responses={409: {}},
|
|
200
204
|
response_model=self.schema.for_item(),
|
|
201
205
|
include_in_schema=is_documented,
|
|
206
|
+
summary="Create One",
|
|
202
207
|
)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
) -> _Response:
|
|
208
|
+
|
|
209
|
+
return self
|
|
210
|
+
|
|
211
|
+
def create_one(self, User, ParentId, Item) -> Callable[..., _Response]: # type: ignore
|
|
212
|
+
def endpoint(user: User, parent_id: ParentId, item: Item) -> _Response:
|
|
208
213
|
try:
|
|
209
214
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
210
215
|
except DoesNotExistError as e:
|
|
@@ -219,35 +224,41 @@ class RestfulRouter:
|
|
|
219
224
|
|
|
220
225
|
return self.response.created_one(item)
|
|
221
226
|
|
|
222
|
-
return
|
|
227
|
+
return endpoint
|
|
223
228
|
|
|
224
229
|
def with_create_many_endpoint(
|
|
225
230
|
self,
|
|
226
231
|
is_documented: bool = True,
|
|
227
|
-
extract_user: Callable[
|
|
232
|
+
extract_user: Callable[..., Any] = no_user,
|
|
228
233
|
) -> Self:
|
|
229
|
-
|
|
230
|
-
str,
|
|
231
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
232
|
-
]
|
|
233
|
-
|
|
234
|
-
collection_type = Annotated[
|
|
235
|
-
RawCollection,
|
|
236
|
-
Depends(self.schema.for_create_many()),
|
|
237
|
-
]
|
|
238
|
-
|
|
239
|
-
@self.router.post(
|
|
234
|
+
self.router.add_api_route(
|
|
240
235
|
"/batch",
|
|
236
|
+
self.create_many(
|
|
237
|
+
User=Annotated[
|
|
238
|
+
Any,
|
|
239
|
+
Depends(extract_user),
|
|
240
|
+
],
|
|
241
|
+
ParentId=Annotated[
|
|
242
|
+
str,
|
|
243
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
244
|
+
],
|
|
245
|
+
Collection=Annotated[
|
|
246
|
+
RawCollection,
|
|
247
|
+
Depends(self.schema.for_create_many()),
|
|
248
|
+
],
|
|
249
|
+
),
|
|
250
|
+
methods=["POST"],
|
|
241
251
|
status_code=201,
|
|
242
252
|
responses={409: {}},
|
|
243
253
|
response_model=self.schema.for_collection(),
|
|
244
254
|
include_in_schema=is_documented,
|
|
255
|
+
summary="Create Many",
|
|
245
256
|
)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
) -> _Response:
|
|
257
|
+
|
|
258
|
+
return self
|
|
259
|
+
|
|
260
|
+
def create_many(self, User, ParentId, Collection) -> Callable[..., _Response]: # type: ignore
|
|
261
|
+
def endpoint(user: User, parent_id: ParentId, items: Collection) -> _Response:
|
|
251
262
|
try:
|
|
252
263
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
253
264
|
except DoesNotExistError as e:
|
|
@@ -260,31 +271,41 @@ class RestfulRouter:
|
|
|
260
271
|
except ExistsError as e:
|
|
261
272
|
return JSONResponse(self.response.exists(e), 409)
|
|
262
273
|
|
|
263
|
-
return
|
|
274
|
+
return endpoint
|
|
264
275
|
|
|
265
276
|
def with_read_one_endpoint(
|
|
266
277
|
self,
|
|
267
278
|
is_documented: bool = True,
|
|
268
|
-
extract_user: Callable[
|
|
279
|
+
extract_user: Callable[..., Any] = no_user,
|
|
269
280
|
) -> Self:
|
|
270
|
-
|
|
271
|
-
parent_id_type = Annotated[
|
|
272
|
-
str,
|
|
273
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
274
|
-
]
|
|
275
|
-
|
|
276
|
-
@self.router.get(
|
|
281
|
+
self.router.add_api_route(
|
|
277
282
|
self.item_path,
|
|
283
|
+
self.read_one(
|
|
284
|
+
User=Annotated[
|
|
285
|
+
Any,
|
|
286
|
+
Depends(extract_user),
|
|
287
|
+
],
|
|
288
|
+
ParentId=Annotated[
|
|
289
|
+
str,
|
|
290
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
291
|
+
],
|
|
292
|
+
ItemId=Annotated[
|
|
293
|
+
str,
|
|
294
|
+
Path(alias=self.id_alias),
|
|
295
|
+
],
|
|
296
|
+
),
|
|
297
|
+
methods=["GET"],
|
|
278
298
|
status_code=200,
|
|
279
299
|
responses={404: {}},
|
|
280
300
|
response_model=self.schema.for_item(),
|
|
281
301
|
include_in_schema=is_documented,
|
|
302
|
+
summary="Read One",
|
|
282
303
|
)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
) -> _Response:
|
|
304
|
+
|
|
305
|
+
return self
|
|
306
|
+
|
|
307
|
+
def read_one(self, User, ParentId, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
308
|
+
def endpoint(user: User, parent_id: ParentId, item_id: ItemId) -> _Response:
|
|
288
309
|
try:
|
|
289
310
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
290
311
|
except DoesNotExistError as e:
|
|
@@ -297,29 +318,37 @@ class RestfulRouter:
|
|
|
297
318
|
except DoesNotExistError as e:
|
|
298
319
|
return JSONResponse(self.response.not_found(e), 404)
|
|
299
320
|
|
|
300
|
-
return
|
|
321
|
+
return endpoint
|
|
301
322
|
|
|
302
323
|
def with_read_all_endpoint(
|
|
303
324
|
self,
|
|
304
325
|
is_documented: bool = True,
|
|
305
|
-
extract_user: Callable[
|
|
326
|
+
extract_user: Callable[..., Any] = no_user,
|
|
306
327
|
) -> Self:
|
|
307
|
-
|
|
308
|
-
str,
|
|
309
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
310
|
-
]
|
|
311
|
-
|
|
312
|
-
@self.router.get(
|
|
328
|
+
self.router.add_api_route(
|
|
313
329
|
"",
|
|
330
|
+
self.read_all(
|
|
331
|
+
User=Annotated[
|
|
332
|
+
Any,
|
|
333
|
+
Depends(extract_user),
|
|
334
|
+
],
|
|
335
|
+
ParentId=Annotated[
|
|
336
|
+
str,
|
|
337
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
338
|
+
],
|
|
339
|
+
),
|
|
340
|
+
methods=["GET"],
|
|
314
341
|
status_code=200,
|
|
315
342
|
responses={},
|
|
316
343
|
response_model=self.schema.for_collection(),
|
|
317
344
|
include_in_schema=is_documented,
|
|
345
|
+
summary="Read All",
|
|
318
346
|
)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
347
|
+
|
|
348
|
+
return self
|
|
349
|
+
|
|
350
|
+
def read_all(self, User, ParentId) -> Callable[..., _Response]: # type: ignore
|
|
351
|
+
def endpoint(user: User, parent_id: ParentId) -> _Response:
|
|
323
352
|
try:
|
|
324
353
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
325
354
|
except DoesNotExistError as e:
|
|
@@ -329,35 +358,49 @@ class RestfulRouter:
|
|
|
329
358
|
|
|
330
359
|
return self.response.found_many(list(service.read_all()))
|
|
331
360
|
|
|
332
|
-
return
|
|
361
|
+
return endpoint
|
|
333
362
|
|
|
334
363
|
def with_update_one_endpoint(
|
|
335
364
|
self,
|
|
336
365
|
is_documented: bool = True,
|
|
337
|
-
extract_user: Callable[
|
|
366
|
+
extract_user: Callable[..., Any] = no_user,
|
|
338
367
|
) -> Self:
|
|
339
|
-
|
|
340
|
-
str,
|
|
341
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
342
|
-
]
|
|
343
|
-
id_type = Annotated[str, Path(alias=self.id_alias)]
|
|
344
|
-
update_type = Annotated[
|
|
345
|
-
RawItem,
|
|
346
|
-
Depends(self.schema.for_update_one()),
|
|
347
|
-
]
|
|
348
|
-
|
|
349
|
-
@self.router.patch(
|
|
368
|
+
self.router.add_api_route(
|
|
350
369
|
self.item_path,
|
|
370
|
+
self.update_one(
|
|
371
|
+
User=Annotated[
|
|
372
|
+
Any,
|
|
373
|
+
Depends(extract_user),
|
|
374
|
+
],
|
|
375
|
+
ParentId=Annotated[
|
|
376
|
+
str,
|
|
377
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
378
|
+
],
|
|
379
|
+
ItemId=Annotated[
|
|
380
|
+
str,
|
|
381
|
+
Path(alias=self.id_alias),
|
|
382
|
+
],
|
|
383
|
+
Updates=Annotated[
|
|
384
|
+
RawItem,
|
|
385
|
+
Depends(self.schema.for_update_one()),
|
|
386
|
+
],
|
|
387
|
+
),
|
|
388
|
+
methods=["PATCH"],
|
|
351
389
|
status_code=200,
|
|
352
390
|
responses={404: {}},
|
|
353
391
|
response_model=self.schema.for_no_data(),
|
|
354
392
|
include_in_schema=is_documented,
|
|
393
|
+
summary="Update One",
|
|
355
394
|
)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
395
|
+
|
|
396
|
+
return self
|
|
397
|
+
|
|
398
|
+
def update_one(self, User, ParentId, ItemId, Updates) -> Callable[..., _Response]: # type: ignore
|
|
399
|
+
def endpoint(
|
|
400
|
+
user: User,
|
|
401
|
+
parent_id: ParentId,
|
|
402
|
+
item_id: ItemId,
|
|
403
|
+
updates: Updates,
|
|
361
404
|
) -> _Response:
|
|
362
405
|
try:
|
|
363
406
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
@@ -374,34 +417,41 @@ class RestfulRouter:
|
|
|
374
417
|
|
|
375
418
|
return self.response.ok()
|
|
376
419
|
|
|
377
|
-
return
|
|
420
|
+
return endpoint
|
|
378
421
|
|
|
379
422
|
def with_update_many_endpoint(
|
|
380
423
|
self,
|
|
381
424
|
is_documented: bool = True,
|
|
382
|
-
extract_user: Callable[
|
|
425
|
+
extract_user: Callable[..., Any] = no_user,
|
|
383
426
|
) -> Self:
|
|
384
|
-
|
|
385
|
-
str,
|
|
386
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
387
|
-
]
|
|
388
|
-
collection_type = Annotated[
|
|
389
|
-
RawCollection,
|
|
390
|
-
Depends(self.schema.for_update_many()),
|
|
391
|
-
]
|
|
392
|
-
|
|
393
|
-
@self.router.patch(
|
|
427
|
+
self.router.add_api_route(
|
|
394
428
|
"",
|
|
429
|
+
self.update_many(
|
|
430
|
+
User=Annotated[
|
|
431
|
+
Any,
|
|
432
|
+
Depends(extract_user),
|
|
433
|
+
],
|
|
434
|
+
ParentId=Annotated[
|
|
435
|
+
str,
|
|
436
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
437
|
+
],
|
|
438
|
+
Collection=Annotated[
|
|
439
|
+
RawCollection,
|
|
440
|
+
Depends(self.schema.for_update_many()),
|
|
441
|
+
],
|
|
442
|
+
),
|
|
443
|
+
methods=["PATCH"],
|
|
395
444
|
status_code=200,
|
|
396
445
|
responses={},
|
|
397
446
|
response_model=self.schema.for_no_data(),
|
|
398
447
|
include_in_schema=is_documented,
|
|
448
|
+
summary="Update Many",
|
|
399
449
|
)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
) -> _Response:
|
|
450
|
+
|
|
451
|
+
return self
|
|
452
|
+
|
|
453
|
+
def update_many(self, User, ParentId, Collection) -> Callable[..., _Response]: # type: ignore
|
|
454
|
+
def endpoint(user: User, parent_id: ParentId, items: Collection) -> _Response:
|
|
405
455
|
try:
|
|
406
456
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
407
457
|
except DoesNotExistError as e:
|
|
@@ -413,31 +463,41 @@ class RestfulRouter:
|
|
|
413
463
|
|
|
414
464
|
return self.response.ok()
|
|
415
465
|
|
|
416
|
-
return
|
|
466
|
+
return endpoint
|
|
417
467
|
|
|
418
468
|
def with_delete_one_endpoint(
|
|
419
469
|
self,
|
|
420
470
|
is_documented: bool = True,
|
|
421
|
-
extract_user: Callable[
|
|
471
|
+
extract_user: Callable[..., Any] = no_user,
|
|
422
472
|
) -> Self:
|
|
423
|
-
|
|
424
|
-
str,
|
|
425
|
-
Path(alias=self.parent_id_alias, default_factory=str),
|
|
426
|
-
]
|
|
427
|
-
id_type = Annotated[str, Path(alias=self.id_alias)]
|
|
428
|
-
|
|
429
|
-
@self.router.delete(
|
|
473
|
+
self.router.add_api_route(
|
|
430
474
|
self.item_path,
|
|
475
|
+
self.delete_one(
|
|
476
|
+
User=Annotated[
|
|
477
|
+
Any,
|
|
478
|
+
Depends(extract_user),
|
|
479
|
+
],
|
|
480
|
+
ParentId=Annotated[
|
|
481
|
+
str,
|
|
482
|
+
Path(alias=self.parent_id_alias, default_factory=str),
|
|
483
|
+
],
|
|
484
|
+
ItemId=Annotated[
|
|
485
|
+
str,
|
|
486
|
+
Path(alias=self.id_alias),
|
|
487
|
+
],
|
|
488
|
+
),
|
|
489
|
+
methods=["DELETE"],
|
|
431
490
|
status_code=200,
|
|
432
491
|
responses={404: {}},
|
|
433
492
|
response_model=self.schema.for_no_data(),
|
|
434
493
|
include_in_schema=is_documented,
|
|
494
|
+
summary="Delete One",
|
|
435
495
|
)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
) -> _Response:
|
|
496
|
+
|
|
497
|
+
return self
|
|
498
|
+
|
|
499
|
+
def delete_one(self, User, ParentId, ItemId) -> Callable[..., _Response]: # type: ignore
|
|
500
|
+
def endpoint(user: User, parent_id: ParentId, item_id: ItemId) -> _Response:
|
|
441
501
|
try:
|
|
442
502
|
service = self.infra.with_user(user).with_parent(parent_id).build()
|
|
443
503
|
except DoesNotExistError as e:
|
|
@@ -452,7 +512,7 @@ class RestfulRouter:
|
|
|
452
512
|
|
|
453
513
|
return self.response.ok()
|
|
454
514
|
|
|
455
|
-
return
|
|
515
|
+
return endpoint
|
|
456
516
|
|
|
457
517
|
def with_sub_resource(self, **names: APIRouter) -> Self:
|
|
458
518
|
for name, router in names.items():
|
|
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
|