apexdevkit 1.13.7__tar.gz → 1.13.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.
Files changed (45) hide show
  1. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/PKG-INFO +1 -1
  2. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/router.py +0 -1
  3. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/formatter.py +9 -0
  4. apexdevkit-1.13.9/apexdevkit/key_fn.py +12 -0
  5. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/__init__.py +7 -1
  6. apexdevkit-1.13.9/apexdevkit/repository/in_memory.py +197 -0
  7. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/pyproject.toml +1 -1
  8. apexdevkit-1.13.7/apexdevkit/repository/alternative/__init__.py +0 -7
  9. apexdevkit-1.13.7/apexdevkit/repository/alternative/base.py +0 -49
  10. apexdevkit-1.13.7/apexdevkit/repository/alternative/formatter_repository.py +0 -50
  11. apexdevkit-1.13.7/apexdevkit/repository/in_memory.py +0 -90
  12. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/LICENSE +0 -0
  13. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/README.md +0 -0
  14. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/__init__.py +0 -0
  15. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/annotation/__init__.py +0 -0
  16. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/annotation/deprecate.py +0 -0
  17. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/environment.py +0 -0
  18. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/error.py +0 -0
  19. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/__init__.py +0 -0
  20. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/builder.py +0 -0
  21. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/dependable.py +0 -0
  22. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/docs.py +0 -0
  23. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/resource.py +0 -0
  24. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/response.py +0 -0
  25. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/schema.py +0 -0
  26. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fastapi/service.py +0 -0
  27. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/fluent.py +0 -0
  28. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/__init__.py +0 -0
  29. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/fake.py +0 -0
  30. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/fluent.py +0 -0
  31. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/httpx.py +0 -0
  32. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/json.py +0 -0
  33. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/http/url.py +0 -0
  34. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/py.typed +0 -0
  35. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/base.py +0 -0
  36. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/connector.py +0 -0
  37. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/database.py +0 -0
  38. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/decorator.py +0 -0
  39. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/interface.py +0 -0
  40. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/mongo.py +0 -0
  41. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/repository/sqlite.py +0 -0
  42. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/testing/__init__.py +0 -0
  43. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/testing/database.py +0 -0
  44. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/testing/fake.py +0 -0
  45. {apexdevkit-1.13.7 → apexdevkit-1.13.9}/apexdevkit/testing/rest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apexdevkit
3
- Version: 1.13.7
3
+ Version: 1.13.9
4
4
  Summary: Apex Development Tools for python.
5
5
  Author: Apex Dev
6
6
  Author-email: dev@apex.ge
@@ -281,7 +281,6 @@ class RestfulRouter:
281
281
 
282
282
  def with_sub_resource(self, **names: APIRouter) -> Self:
283
283
  for name, router in names.items():
284
- print(self.item_path)
285
284
  self.router.include_router(router, prefix=f"{self.item_path}/{name}")
286
285
 
287
286
  return self
@@ -14,6 +14,15 @@ class Formatter(Protocol[_SourceT, _TargetT]): # pragma: no cover
14
14
  pass
15
15
 
16
16
 
17
+ @dataclass
18
+ class NoFormatter(Formatter[Any, Any]):
19
+ def load(self, source: Any) -> Any:
20
+ return source
21
+
22
+ def dump(self, target: Any) -> Any:
23
+ return target
24
+
25
+
17
26
  @dataclass
18
27
  class ListFormatter(Generic[_SourceT, _TargetT]):
19
28
  inner: Formatter[_SourceT, _TargetT]
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+
7
+ @dataclass
8
+ class AttributeKey:
9
+ name: str
10
+
11
+ def __call__(self, item: Any) -> str:
12
+ return str(getattr(item, self.name))
@@ -6,7 +6,11 @@ from apexdevkit.repository.database import (
6
6
  Database,
7
7
  DatabaseCommand,
8
8
  )
9
- from apexdevkit.repository.in_memory import InMemoryRepository
9
+ from apexdevkit.repository.in_memory import (
10
+ InMemoryKeyValueStore,
11
+ InMemoryRepository,
12
+ KeyValueStore,
13
+ )
10
14
  from apexdevkit.repository.interface import Repository
11
15
 
12
16
  __all__ = [
@@ -16,6 +20,8 @@ __all__ = [
16
20
  "Database",
17
21
  "DatabaseCommand",
18
22
  "InMemoryRepository",
23
+ "InMemoryKeyValueStore",
24
+ "KeyValueStore",
19
25
  "Repository",
20
26
  "RepositoryBase",
21
27
  ]
@@ -0,0 +1,197 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any, Callable, Generic, Iterable, Iterator, Protocol, Self
5
+
6
+ from apexdevkit.error import DoesNotExistError, ExistsError
7
+ from apexdevkit.formatter import Formatter, NoFormatter
8
+ from apexdevkit.key_fn import AttributeKey
9
+ from apexdevkit.repository import RepositoryBase
10
+ from apexdevkit.repository.interface import ItemT, Repository
11
+
12
+ KeyFunction = Callable[[Any], str]
13
+ _Raw = dict[str, Any]
14
+
15
+
16
+ @dataclass
17
+ class InMemoryRepository(Generic[ItemT]):
18
+ store: KeyValueStore[ItemT] = field(default_factory=lambda: InMemoryKeyValueStore())
19
+ keys: list[KeyFunction] = field(default_factory=list)
20
+ seeds: list[ItemT] = field(default_factory=list)
21
+
22
+ def with_formatter(self, value: Formatter[_Raw, ItemT]) -> Self:
23
+ return self.with_store(InMemoryKeyValueStore(value))
24
+
25
+ def with_store(self, value: KeyValueStore[ItemT]) -> Self:
26
+ self.store = value
27
+
28
+ return self
29
+
30
+ def and_key(self, function: KeyFunction) -> Self:
31
+ return self.with_key(function)
32
+
33
+ def with_key(self, function: KeyFunction) -> Self:
34
+ self.keys.append(function)
35
+
36
+ return self
37
+
38
+ def and_seeded(self, *items: ItemT) -> Self:
39
+ return self.with_seeded(*items)
40
+
41
+ def with_seeded(self, *items: ItemT) -> Self:
42
+ self.seeds.extend(items)
43
+
44
+ return self
45
+
46
+ def build(self) -> Repository[ItemT]:
47
+ return self._seed(self._create())
48
+
49
+ def _seed(self, repository: Repository[ItemT]) -> Repository[ItemT]:
50
+ for seed in self.seeds:
51
+ repository.create(seed)
52
+
53
+ return repository
54
+
55
+ def _create(self) -> Repository[ItemT]:
56
+ match len(self.keys):
57
+ case 0:
58
+ return _SingleKeyRepository(self.store, pk=AttributeKey("id"))
59
+ case 1:
60
+ return _SingleKeyRepository(self.store, pk=self.keys[0])
61
+ case _:
62
+ return _ManyKeyRepository(self.store, keys=self.keys)
63
+
64
+
65
+ class KeyValueStore(Protocol[ItemT]): # pragma: no cover
66
+ def count(self) -> int:
67
+ pass
68
+
69
+ def set(self, key: str, value: ItemT) -> None:
70
+ pass
71
+
72
+ def get(self, key: str) -> ItemT:
73
+ pass
74
+
75
+ def drop(self, key: str) -> None:
76
+ pass
77
+
78
+ def values(self) -> Iterable[ItemT]:
79
+ pass
80
+
81
+
82
+ @dataclass
83
+ class InMemoryKeyValueStore(Generic[ItemT]):
84
+ formatter: Formatter[_Raw, ItemT] = field(default_factory=NoFormatter)
85
+ items: dict[str, _Raw] = field(default_factory=dict)
86
+
87
+ def count(self) -> int:
88
+ return len(self.items)
89
+
90
+ def set(self, key: str, value: ItemT) -> None:
91
+ self.items[key] = self.formatter.dump(value)
92
+
93
+ def get(self, key: str) -> ItemT:
94
+ return self.formatter.load(self.items[key])
95
+
96
+ def drop(self, key: str) -> None:
97
+ del self.items[key]
98
+
99
+ def values(self) -> Iterable[ItemT]:
100
+ for raw in self.items.values():
101
+ yield self.formatter.load(raw)
102
+
103
+
104
+ @dataclass
105
+ class _SingleKeyRepository(RepositoryBase[ItemT]):
106
+ store: KeyValueStore[ItemT]
107
+ pk: KeyFunction
108
+
109
+ def bind(self, **kwargs: Any) -> Self: # pragma: no cover
110
+ return self
111
+
112
+ def create(self, item: ItemT) -> ItemT:
113
+ self._ensure_does_not_exist(item)
114
+ self.store.set(self.pk(item), item)
115
+
116
+ return item
117
+
118
+ def _ensure_does_not_exist(self, new: ItemT) -> None:
119
+ try:
120
+ existing = self.store.get(self.pk(new))
121
+ except KeyError:
122
+ return
123
+
124
+ ExistsError(existing).with_duplicate(self.pk).fire()
125
+
126
+ def update(self, item: ItemT) -> None:
127
+ self.delete(self.pk(item))
128
+ self.create(item)
129
+
130
+ def delete(self, item_id: str) -> None:
131
+ try:
132
+ self.store.drop(item_id)
133
+ except KeyError:
134
+ raise DoesNotExistError(item_id)
135
+
136
+ def read(self, item_id: str) -> ItemT:
137
+ try:
138
+ return self.store.get(item_id)
139
+ except KeyError:
140
+ raise DoesNotExistError(item_id)
141
+
142
+ def __iter__(self) -> Iterator[ItemT]:
143
+ return iter(self.store.values())
144
+
145
+ def __len__(self) -> int:
146
+ return self.store.count()
147
+
148
+
149
+ @dataclass
150
+ class _ManyKeyRepository(RepositoryBase[ItemT]):
151
+ store: KeyValueStore[ItemT]
152
+
153
+ keys: list[KeyFunction] = field(default_factory=list)
154
+
155
+ def bind(self, **kwargs: Any) -> Self: # pragma: no cover
156
+ return self
157
+
158
+ def create(self, item: ItemT) -> ItemT:
159
+ self._ensure_does_not_exist(item)
160
+ self.store.set(self._pk(item), item)
161
+
162
+ return item
163
+
164
+ def _ensure_does_not_exist(self, new: ItemT) -> None:
165
+ for existing in self:
166
+ error = ExistsError(existing)
167
+
168
+ for key in self.keys:
169
+ if key(new) == key(existing):
170
+ error.with_duplicate(key)
171
+
172
+ error.fire()
173
+
174
+ def _pk(self, item: ItemT) -> Any:
175
+ return self.keys[0](item)
176
+
177
+ def update(self, item: ItemT) -> None:
178
+ self.delete(self._pk(item))
179
+ self.create(item)
180
+
181
+ def delete(self, item_id: str) -> None:
182
+ item = self.read(item_id)
183
+ self.store.drop(self._pk(item))
184
+
185
+ def read(self, item_id: str) -> ItemT:
186
+ for key in self.keys:
187
+ for item in self:
188
+ if key(item) == str(item_id):
189
+ return item
190
+
191
+ raise DoesNotExistError(item_id)
192
+
193
+ def __iter__(self) -> Iterator[ItemT]:
194
+ return iter(self.store.values())
195
+
196
+ def __len__(self) -> int:
197
+ return self.store.count()
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "apexdevkit"
3
- version = "1.13.7"
3
+ version = "1.13.9"
4
4
  description = "Apex Development Tools for python."
5
5
  authors = ["Apex Dev <dev@apex.ge>"]
6
6
  readme = "README.md"
@@ -1,7 +0,0 @@
1
- from apexdevkit.repository.alternative.base import MemoryPersistence
2
- from apexdevkit.repository.alternative.formatter_repository import FormatterRepository
3
-
4
- __all__ = [
5
- "MemoryPersistence",
6
- "FormatterRepository",
7
- ]
@@ -1,49 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from typing import Any, Iterator
3
-
4
- from apexdevkit.error import DoesNotExistError, ExistsError
5
-
6
- _Raw = dict[str, Any]
7
-
8
-
9
- @dataclass
10
- class MemoryPersistence: # pragma: no cover
11
- items: dict[str, _Raw] = field(init=False, default_factory=dict)
12
-
13
- def create(self, item: _Raw) -> _Raw:
14
- self._ensure_does_not_exist(item)
15
- self.items[item["id"]] = item
16
-
17
- return item
18
-
19
- def _ensure_does_not_exist(self, new: _Raw) -> None:
20
- if new["id"] in self.items.keys():
21
- error = ExistsError(self.items[new["id"]])
22
- error.with_duplicate(lambda item: f"id<{item['id']}>")
23
- error.fire()
24
-
25
- def read(self, item_id: str) -> _Raw:
26
- self._ensure_exists(item_id)
27
-
28
- return self.items[item_id]
29
-
30
- def _ensure_exists(self, item_id: str) -> None:
31
- if item_id not in self.items.keys():
32
- raise DoesNotExistError(item_id)
33
-
34
- def update(self, item: _Raw) -> None:
35
- self._ensure_exists(item["id"])
36
-
37
- self.delete(item["id"])
38
- self.create(item)
39
-
40
- def delete(self, item_id: str) -> None:
41
- self._ensure_exists(item_id)
42
-
43
- self.items.pop(item_id)
44
-
45
- def __iter__(self) -> Iterator[_Raw]:
46
- yield from self.items.values()
47
-
48
- def __len__(self) -> int:
49
- return len(self.items)
@@ -1,50 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Any, Generic, Iterator, Self
3
-
4
- from apexdevkit.formatter import Formatter
5
- from apexdevkit.repository.alternative import MemoryPersistence
6
- from apexdevkit.repository.interface import ItemT
7
-
8
- _Raw = dict[str, Any]
9
-
10
-
11
- @dataclass
12
- class FormatterRepository(Generic[ItemT]):
13
- base: MemoryPersistence
14
- formatter: Formatter[_Raw, ItemT]
15
-
16
- def create(self, item: ItemT) -> ItemT:
17
- return self.formatter.load(self.base.create(self.formatter.dump(item)))
18
-
19
- def create_many(self, items: list[ItemT]) -> list[ItemT]:
20
- return [
21
- self.formatter.load(
22
- self.base.create(
23
- self.formatter.dump(item),
24
- ),
25
- )
26
- for item in items
27
- ]
28
-
29
- def read(self, item_id: str) -> ItemT:
30
- return self.formatter.load(self.base.read(item_id))
31
-
32
- def update(self, item: ItemT) -> None:
33
- self.base.update(self.formatter.dump(item))
34
-
35
- def update_many(self, items: list[ItemT]) -> None:
36
- for item in items:
37
- self.base.update(self.formatter.dump(item))
38
-
39
- def delete(self, item_id: str) -> None:
40
- self.base.delete(item_id)
41
-
42
- def bind(self, **kwargs: Any) -> Self:
43
- return self
44
-
45
- def __iter__(self) -> Iterator[ItemT]:
46
- for raw in self.base:
47
- yield self.formatter.load(raw)
48
-
49
- def __len__(self) -> int:
50
- return len(self.base)
@@ -1,90 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from typing import Any, Callable, Iterable, Iterator, Self
3
-
4
- from apexdevkit.error import DoesNotExistError, ExistsError
5
- from apexdevkit.formatter import Formatter
6
- from apexdevkit.repository import RepositoryBase
7
- from apexdevkit.repository.interface import ItemT
8
-
9
- KeyFunction = Callable[[Any], str]
10
- _Raw = dict[str, Any]
11
-
12
-
13
- @dataclass
14
- class AttributeKey:
15
- name: str
16
-
17
- def __call__(self, item: Any) -> str:
18
- return str(getattr(item, self.name))
19
-
20
-
21
- @dataclass
22
- class InMemoryRepository(RepositoryBase[ItemT]):
23
- formatter: Formatter[_Raw, ItemT]
24
- items: dict[str, _Raw] = field(default_factory=dict)
25
-
26
- _keys: list[KeyFunction] = field(init=False, default_factory=list)
27
-
28
- def bind(self, **kwargs: Any) -> Self:
29
- return self
30
-
31
- def with_key(self, function: KeyFunction) -> Self:
32
- self._keys.append(function)
33
-
34
- return self
35
-
36
- def with_seeded(self, *items: ItemT) -> Self:
37
- for item in items:
38
- self.create(item)
39
-
40
- return self
41
-
42
- def create(self, item: ItemT) -> ItemT:
43
- self._ensure_does_not_exist(item)
44
- self.items[self._pk(item)] = self.formatter.dump(item)
45
-
46
- return item
47
-
48
- def _ensure_does_not_exist(self, new: ItemT) -> None:
49
- for existing in self:
50
- error = ExistsError(existing)
51
-
52
- for key in self._keys:
53
- if key(new) == key(existing):
54
- error.with_duplicate(key)
55
-
56
- error.fire()
57
-
58
- def _pk(self, item: ItemT) -> Any:
59
- return self._keys[0](item)
60
-
61
- def update(self, item: ItemT) -> None:
62
- self.delete(self._pk(item))
63
- self.create(item)
64
-
65
- def delete(self, item_id: str) -> None:
66
- item = self.read(item_id)
67
- del self.items[self._pk(item)]
68
-
69
- def read(self, item_id: str) -> ItemT:
70
- for key in self._keys:
71
- for item in self:
72
- if key(item) == str(item_id):
73
- return item
74
-
75
- raise DoesNotExistError(item_id)
76
-
77
- def __iter__(self) -> Iterator[ItemT]:
78
- yield from [self.formatter.load(raw) for raw in self.items.values()]
79
-
80
- def __len__(self) -> int:
81
- return len(self.items)
82
-
83
- def search(self, **kwargs: Any) -> Iterable[ItemT]:
84
- items = []
85
-
86
- for item in self.items.values():
87
- if kwargs.items() <= item.items():
88
- items.append(self.formatter.load(item))
89
-
90
- return items
File without changes
File without changes