apexdevkit 1.1.2__tar.gz → 1.2.1__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.1.2 → apexdevkit-1.2.1}/PKG-INFO +1 -1
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/router.py +5 -5
- apexdevkit-1.2.1/apexdevkit/fastapi/service.py +86 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/repository/in_memory.py +16 -1
- apexdevkit-1.2.1/apexdevkit/repository/interface.py +30 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/pyproject.toml +1 -1
- apexdevkit-1.1.2/apexdevkit/fastapi/service.py +0 -85
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/LICENSE +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/README.md +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/error.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.1.2 → apexdevkit-1.2.1}/apexdevkit/testing/rest.py +0 -0
|
@@ -6,7 +6,7 @@ from fastapi.responses import JSONResponse
|
|
|
6
6
|
|
|
7
7
|
from apexdevkit.error import DoesNotExistError, ExistsError
|
|
8
8
|
from apexdevkit.fastapi.schema import RestfulSchema
|
|
9
|
-
from apexdevkit.fastapi.service import
|
|
9
|
+
from apexdevkit.fastapi.service import RawCollection, RawItem, RestfulService
|
|
10
10
|
from apexdevkit.testing import RestfulName
|
|
11
11
|
|
|
12
12
|
_Response = JSONResponse | dict[str, Any]
|
|
@@ -115,7 +115,7 @@ class RestfulRouter:
|
|
|
115
115
|
response_model=self.schema.for_item(),
|
|
116
116
|
include_in_schema=is_documented,
|
|
117
117
|
)
|
|
118
|
-
def create_one(item: Annotated[
|
|
118
|
+
def create_one(item: Annotated[RawItem, Depends(schema)]) -> _Response:
|
|
119
119
|
try:
|
|
120
120
|
item = self.service.create_one(item)
|
|
121
121
|
except ExistsError as e:
|
|
@@ -135,7 +135,7 @@ class RestfulRouter:
|
|
|
135
135
|
response_model=self.schema.for_collection(),
|
|
136
136
|
include_in_schema=is_documented,
|
|
137
137
|
)
|
|
138
|
-
def create_many(items: Annotated[
|
|
138
|
+
def create_many(items: Annotated[RawCollection, Depends(schema)]) -> _Response:
|
|
139
139
|
try:
|
|
140
140
|
return self.response.created_many(self.service.create_many(items))
|
|
141
141
|
except ExistsError as e:
|
|
@@ -188,7 +188,7 @@ class RestfulRouter:
|
|
|
188
188
|
)
|
|
189
189
|
def update_one(
|
|
190
190
|
item_id: str,
|
|
191
|
-
updates: Annotated[
|
|
191
|
+
updates: Annotated[RawItem, Depends(schema)],
|
|
192
192
|
) -> _Response:
|
|
193
193
|
try:
|
|
194
194
|
self.service.update_one(item_id, **updates)
|
|
@@ -209,7 +209,7 @@ class RestfulRouter:
|
|
|
209
209
|
response_model=self.schema.for_no_data(),
|
|
210
210
|
include_in_schema=is_documented,
|
|
211
211
|
)
|
|
212
|
-
def update_many(items: Annotated[
|
|
212
|
+
def update_many(items: Annotated[RawCollection, Depends(schema)]) -> _Response:
|
|
213
213
|
self.service.update_many(items)
|
|
214
214
|
|
|
215
215
|
return self.response.ok()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from dataclasses import asdict, dataclass, replace
|
|
3
|
+
from typing import Any, Iterable
|
|
4
|
+
|
|
5
|
+
from apexdevkit.repository.interface import Repository
|
|
6
|
+
|
|
7
|
+
RawItem = dict[str, Any]
|
|
8
|
+
RawCollection = Iterable[RawItem]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RestfulService(ABC):
|
|
12
|
+
def create_one(self, item: RawItem) -> RawItem:
|
|
13
|
+
raise NotImplementedError(self.create_one.__name__)
|
|
14
|
+
|
|
15
|
+
def create_many(self, items: RawCollection) -> RawCollection:
|
|
16
|
+
raise NotImplementedError(self.create_many.__name__)
|
|
17
|
+
|
|
18
|
+
def read_one(self, item_id: str) -> RawItem:
|
|
19
|
+
raise NotImplementedError(self.read_one.__name__)
|
|
20
|
+
|
|
21
|
+
def read_all(self) -> RawCollection:
|
|
22
|
+
raise NotImplementedError(self.read_all.__name__)
|
|
23
|
+
|
|
24
|
+
def update_one(self, item_id: str, **with_fields: Any) -> RawItem:
|
|
25
|
+
raise NotImplementedError(self.update_one.__name__)
|
|
26
|
+
|
|
27
|
+
def update_many(self, items: RawCollection) -> RawCollection:
|
|
28
|
+
raise NotImplementedError(self.update_many.__name__)
|
|
29
|
+
|
|
30
|
+
def delete_one(self, item_id: str) -> None:
|
|
31
|
+
raise NotImplementedError(self.delete_one.__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _as_raw_collection(value: Iterable[Any]) -> RawCollection:
|
|
35
|
+
return [_as_raw_item(item) for item in value]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _as_raw_item(value: Any) -> RawItem:
|
|
39
|
+
return asdict(value)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class RestfulRepository(RestfulService):
|
|
44
|
+
resource: type[Any]
|
|
45
|
+
repository: Repository[Any, Any]
|
|
46
|
+
|
|
47
|
+
def create_one(self, item: RawItem) -> RawItem:
|
|
48
|
+
result = self.resource(**item)
|
|
49
|
+
|
|
50
|
+
self.repository.create(result)
|
|
51
|
+
|
|
52
|
+
return _as_raw_item(result)
|
|
53
|
+
|
|
54
|
+
def create_many(self, items: RawCollection) -> RawCollection:
|
|
55
|
+
result = [self.resource(**fields) for fields in items]
|
|
56
|
+
|
|
57
|
+
self.repository.create_many(result)
|
|
58
|
+
|
|
59
|
+
return _as_raw_collection(result)
|
|
60
|
+
|
|
61
|
+
def read_one(self, item_id: str) -> RawItem:
|
|
62
|
+
result = self.repository.read(item_id)
|
|
63
|
+
|
|
64
|
+
return _as_raw_item(result)
|
|
65
|
+
|
|
66
|
+
def read_all(self) -> RawCollection:
|
|
67
|
+
result = self.repository
|
|
68
|
+
|
|
69
|
+
return _as_raw_collection(result)
|
|
70
|
+
|
|
71
|
+
def update_one(self, item_id: str, **with_fields: Any) -> RawItem:
|
|
72
|
+
result = replace(self.repository.read(item_id), **with_fields)
|
|
73
|
+
|
|
74
|
+
self.repository.update(result)
|
|
75
|
+
|
|
76
|
+
return _as_raw_item(result)
|
|
77
|
+
|
|
78
|
+
def update_many(self, items: RawCollection) -> RawCollection:
|
|
79
|
+
result = [self.resource(**fields) for fields in items]
|
|
80
|
+
|
|
81
|
+
self.repository.update_many(result)
|
|
82
|
+
|
|
83
|
+
return _as_raw_collection(result)
|
|
84
|
+
|
|
85
|
+
def delete_one(self, item_id: str) -> None:
|
|
86
|
+
self.repository.delete(item_id)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from copy import deepcopy
|
|
2
|
-
from dataclasses import dataclass, field
|
|
2
|
+
from dataclasses import asdict, dataclass, field
|
|
3
3
|
from typing import Any, Generic, Iterable, Iterator, Protocol, Self, TypeVar
|
|
4
4
|
|
|
5
5
|
from apexdevkit.error import Criteria, DoesNotExistError, ExistsError
|
|
@@ -22,6 +22,17 @@ class _Formatter(Protocol[ItemT]):
|
|
|
22
22
|
pass
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class DataclassFormatter(Generic[ItemT]):
|
|
27
|
+
resource: type[ItemT]
|
|
28
|
+
|
|
29
|
+
def load(self, raw: dict[str, Any]) -> ItemT:
|
|
30
|
+
return self.resource(**raw)
|
|
31
|
+
|
|
32
|
+
def dump(self, item: ItemT) -> dict[str, Any]:
|
|
33
|
+
return asdict(item) # type: ignore
|
|
34
|
+
|
|
35
|
+
|
|
25
36
|
@dataclass
|
|
26
37
|
class InMemoryRepository(Generic[ItemT]):
|
|
27
38
|
formatter: _Formatter[ItemT]
|
|
@@ -30,6 +41,10 @@ class InMemoryRepository(Generic[ItemT]):
|
|
|
30
41
|
_uniques: list[Criteria] = field(init=False, default_factory=list)
|
|
31
42
|
_search_by: list[str] = field(init=False, default_factory=list)
|
|
32
43
|
|
|
44
|
+
@classmethod
|
|
45
|
+
def for_dataclass(cls, value: type[ItemT]) -> "InMemoryRepository[ItemT]":
|
|
46
|
+
return cls(DataclassFormatter(value))
|
|
47
|
+
|
|
33
48
|
def __post_init__(self) -> None:
|
|
34
49
|
self._search_by = ["id", *self._search_by]
|
|
35
50
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Iterator, Protocol, TypeVar
|
|
2
|
+
|
|
3
|
+
ItemT = TypeVar("ItemT")
|
|
4
|
+
IdT = TypeVar("IdT", contravariant=True)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Repository(Protocol[IdT, ItemT]):
|
|
8
|
+
def create(self, item: ItemT) -> None:
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
def create_many(self, items: list[ItemT]) -> None:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
def read(self, item_id: IdT) -> ItemT:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
def update(self, item: ItemT) -> None:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def update_many(self, items: list[ItemT]) -> None:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
def delete(self, item_id: IdT) -> None:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
def __iter__(self) -> Iterator[ItemT]:
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
def __len__(self) -> int:
|
|
30
|
+
pass
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
from dataclasses import asdict, dataclass, replace
|
|
2
|
-
from typing import Any, Iterable, Protocol
|
|
3
|
-
|
|
4
|
-
from apexdevkit.repository import InMemoryRepository
|
|
5
|
-
|
|
6
|
-
_RawItem = dict[str, Any]
|
|
7
|
-
_RawCollection = Iterable[_RawItem]
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class RestfulService(Protocol):
|
|
11
|
-
def create_one(self, item: _RawItem) -> _RawItem:
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
def create_many(self, items: _RawCollection) -> _RawCollection:
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
def read_one(self, item_id: str) -> _RawItem:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
def read_all(self) -> _RawCollection:
|
|
21
|
-
pass
|
|
22
|
-
|
|
23
|
-
def update_one(self, item_id: str, **with_fields: Any) -> _RawItem:
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
def update_many(self, items: _RawCollection) -> _RawCollection:
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
def delete_one(self, item_id: str) -> None:
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _as_raw_collection(value: Iterable[Any]) -> _RawCollection:
|
|
34
|
-
return [_as_raw_item(item) for item in value]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _as_raw_item(value: Any) -> _RawItem:
|
|
38
|
-
return asdict(value)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@dataclass
|
|
42
|
-
class InMemoryRestfulService:
|
|
43
|
-
resource: type[Any]
|
|
44
|
-
repository: InMemoryRepository[Any]
|
|
45
|
-
|
|
46
|
-
def create_one(self, item: _RawItem) -> _RawItem:
|
|
47
|
-
result = self.resource(**item)
|
|
48
|
-
|
|
49
|
-
self.repository.create(result)
|
|
50
|
-
|
|
51
|
-
return _as_raw_item(result)
|
|
52
|
-
|
|
53
|
-
def create_many(self, items: _RawCollection) -> _RawCollection:
|
|
54
|
-
result = [self.resource(**fields) for fields in items]
|
|
55
|
-
|
|
56
|
-
self.repository.create_many(result)
|
|
57
|
-
|
|
58
|
-
return _as_raw_collection(result)
|
|
59
|
-
|
|
60
|
-
def read_one(self, item_id: str) -> _RawItem:
|
|
61
|
-
result = self.repository.read(item_id)
|
|
62
|
-
|
|
63
|
-
return _as_raw_item(result)
|
|
64
|
-
|
|
65
|
-
def read_all(self) -> _RawCollection:
|
|
66
|
-
result = self.repository
|
|
67
|
-
|
|
68
|
-
return _as_raw_collection(result)
|
|
69
|
-
|
|
70
|
-
def update_one(self, item_id: str, **with_fields: Any) -> _RawItem:
|
|
71
|
-
result = replace(self.repository.read(item_id), **with_fields)
|
|
72
|
-
|
|
73
|
-
self.repository.update(result)
|
|
74
|
-
|
|
75
|
-
return _as_raw_item(result)
|
|
76
|
-
|
|
77
|
-
def update_many(self, items: _RawCollection) -> _RawCollection:
|
|
78
|
-
result = [self.resource(**fields) for fields in items]
|
|
79
|
-
|
|
80
|
-
self.repository.update_many(result)
|
|
81
|
-
|
|
82
|
-
return _as_raw_collection(result)
|
|
83
|
-
|
|
84
|
-
def delete_one(self, item_id: str) -> None:
|
|
85
|
-
self.repository.delete(item_id)
|
|
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
|