apexdevkit 1.9.8__tar.gz → 1.9.9__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.9.8 → apexdevkit-1.9.9}/PKG-INFO +1 -1
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/in_memory.py +38 -17
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/pyproject.toml +1 -1
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/LICENSE +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/README.md +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/annotation/deprecate.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/error.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/builder.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/dependable.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/resource.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/response.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/router.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/schema.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fastapi/service.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/fluent.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/formatter.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/fluent.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/httpx.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/base.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/connector.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/database.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/decorator.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/interface.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/mongo.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/repository/sqlite.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/testing/database.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/testing/fake.py +0 -0
- {apexdevkit-1.9.8 → apexdevkit-1.9.9}/apexdevkit/testing/rest.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from copy import deepcopy
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
|
-
from typing import Any, Generic, Iterable, Iterator, Protocol, Self, TypeVar
|
|
3
|
+
from typing import Any, Callable, Generic, Iterable, Iterator, Protocol, Self, TypeVar
|
|
4
4
|
|
|
5
|
-
from apexdevkit.
|
|
5
|
+
from apexdevkit.annotation import deprecated
|
|
6
|
+
from apexdevkit.error import DoesNotExistError, ExistsError
|
|
6
7
|
from apexdevkit.formatter import DataclassFormatter, Formatter
|
|
7
8
|
|
|
8
9
|
|
|
@@ -12,32 +13,54 @@ class _Item(Protocol): # pragma: no cover
|
|
|
12
13
|
pass
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
KeyFunction = Callable[[Any], str]
|
|
17
|
+
|
|
15
18
|
ItemT = TypeVar("ItemT", bound=_Item)
|
|
16
19
|
_Raw = dict[str, Any]
|
|
17
20
|
|
|
18
21
|
|
|
22
|
+
@dataclass
|
|
23
|
+
class AttributeKey:
|
|
24
|
+
name: str
|
|
25
|
+
|
|
26
|
+
def __call__(self, item: Any) -> str:
|
|
27
|
+
return str(getattr(item, self.name))
|
|
28
|
+
|
|
29
|
+
|
|
19
30
|
@dataclass
|
|
20
31
|
class InMemoryRepository(Generic[ItemT]):
|
|
21
32
|
formatter: Formatter[_Raw, ItemT]
|
|
22
33
|
items: dict[str, _Raw] = field(default_factory=dict)
|
|
23
34
|
|
|
24
|
-
|
|
25
|
-
_search_by: list[str] = field(init=False, default_factory=list)
|
|
35
|
+
_key_functions: list[KeyFunction] = field(init=False, default_factory=list)
|
|
26
36
|
|
|
27
37
|
@classmethod
|
|
28
38
|
def for_dataclass(cls, value: type[ItemT]) -> "InMemoryRepository[ItemT]":
|
|
29
39
|
return cls(DataclassFormatter(value))
|
|
30
40
|
|
|
31
41
|
def __post_init__(self) -> None:
|
|
32
|
-
self.
|
|
33
|
-
|
|
42
|
+
self._key_functions = [AttributeKey("id")]
|
|
43
|
+
|
|
44
|
+
@deprecated(
|
|
45
|
+
"""
|
|
46
|
+
.with_searchable() is deprecated. Use .with_key() instead.
|
|
47
|
+
Instead of .with_searchable("code") use .with_key(AttributeKey("code"))
|
|
48
|
+
"""
|
|
49
|
+
)
|
|
34
50
|
def with_searchable(self, attribute: str) -> Self:
|
|
35
|
-
self.
|
|
51
|
+
return self.with_key(AttributeKey(attribute))
|
|
36
52
|
|
|
37
|
-
|
|
53
|
+
@deprecated(
|
|
54
|
+
"""
|
|
55
|
+
.with_unique() is deprecated. Use .with_key() instead.
|
|
56
|
+
Instead of .with_unique(criteria) use .with_key(criteria)
|
|
57
|
+
"""
|
|
58
|
+
)
|
|
59
|
+
def with_unique(self, criteria: KeyFunction) -> Self:
|
|
60
|
+
return self.with_key(criteria)
|
|
38
61
|
|
|
39
|
-
def
|
|
40
|
-
self.
|
|
62
|
+
def with_key(self, function: KeyFunction) -> Self:
|
|
63
|
+
self._key_functions.append(function)
|
|
41
64
|
|
|
42
65
|
return self
|
|
43
66
|
|
|
@@ -62,18 +85,16 @@ class InMemoryRepository(Generic[ItemT]):
|
|
|
62
85
|
for existing in self:
|
|
63
86
|
error = ExistsError(existing)
|
|
64
87
|
|
|
65
|
-
for
|
|
66
|
-
if
|
|
67
|
-
error.with_duplicate(
|
|
88
|
+
for key in self._key_functions:
|
|
89
|
+
if key(new) == key(existing):
|
|
90
|
+
error.with_duplicate(key)
|
|
68
91
|
|
|
69
92
|
error.fire()
|
|
70
93
|
|
|
71
|
-
assert str(new.id) not in self.items, f"Item with id<{new.id}> already exists"
|
|
72
|
-
|
|
73
94
|
def read(self, item_id: Any) -> ItemT:
|
|
74
95
|
for item in self:
|
|
75
|
-
for
|
|
76
|
-
if
|
|
96
|
+
for key in self._key_functions:
|
|
97
|
+
if key(item) == str(item_id):
|
|
77
98
|
return item
|
|
78
99
|
|
|
79
100
|
raise DoesNotExistError(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
|
|
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
|