apexdevkit 1.29.3__tar.gz → 1.30.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.
Files changed (59) hide show
  1. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/PKG-INFO +1 -1
  2. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/service.py +4 -6
  3. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/decorator.py +21 -7
  4. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/interface.py +6 -3
  5. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/pyproject.toml +1 -1
  6. apexdevkit-1.29.3/apexdevkit/id.py +0 -54
  7. apexdevkit-1.29.3/apexdevkit/synchronization.py +0 -48
  8. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/LICENSE +0 -0
  9. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/README.md +0 -0
  10. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/__init__.py +0 -0
  11. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/annotation/__init__.py +0 -0
  12. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/annotation/deprecate.py +0 -0
  13. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/date.py +0 -0
  14. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/environment.py +0 -0
  15. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/error.py +0 -0
  16. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/__init__.py +0 -0
  17. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/builder.py +0 -0
  18. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/dependable.py +0 -0
  19. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/docs.py +0 -0
  20. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/name.py +0 -0
  21. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/resource.py +0 -0
  22. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/response.py +0 -0
  23. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/router.py +0 -0
  24. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fastapi/schema.py +0 -0
  25. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/fluent.py +0 -0
  26. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/formatter.py +0 -0
  27. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/__init__.py +0 -0
  28. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/fake.py +0 -0
  29. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/fluent.py +0 -0
  30. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/httpx/__init__.py +0 -0
  31. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/httpx/client.py +0 -0
  32. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/httpx/hooks.py +0 -0
  33. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/json.py +0 -0
  34. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/http/url.py +0 -0
  35. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/key_fn.py +0 -0
  36. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/py.typed +0 -0
  37. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/query/__init__.py +0 -0
  38. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/query/generator.py +0 -0
  39. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/query/query.py +0 -0
  40. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/__init__.py +0 -0
  41. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/__init__.py +0 -0
  42. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/database.py +0 -0
  43. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/mixin.py +0 -0
  44. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/core/multi.py +0 -0
  45. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/in_memory/__init__.py +0 -0
  46. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/in_memory/mixin.py +0 -0
  47. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/in_memory/repository.py +0 -0
  48. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/in_memory/store.py +0 -0
  49. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/sql/__init__.py +0 -0
  50. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/sql/connector.py +0 -0
  51. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/sql/field.py +0 -0
  52. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/sql/mssql.py +0 -0
  53. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/repository/sql/sqlite.py +0 -0
  54. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/server.py +0 -0
  55. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/testing/__init__.py +0 -0
  56. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/testing/database.py +0 -0
  57. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/testing/fake.py +0 -0
  58. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/testing/rest.py +0 -0
  59. {apexdevkit-1.29.3 → apexdevkit-1.30.1}/apexdevkit/value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexdevkit
3
- Version: 1.29.3
3
+ Version: 1.30.1
4
4
  Summary: Apex Development Tools for python.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
@@ -75,7 +75,7 @@ class RestfulRepository(RestfulService, Generic[ItemT]):
75
75
  def create_many(self, items: RawCollection) -> RawCollection:
76
76
  return [
77
77
  self.formatter.dump(item)
78
- for item in self._batch.create_many(
78
+ for item in self._batch.load(
79
79
  [self.formatter.load(fields) for fields in items]
80
80
  )
81
81
  ]
@@ -102,9 +102,7 @@ class RestfulRepository(RestfulService, Generic[ItemT]):
102
102
 
103
103
  updates.append(self.formatter.load(data))
104
104
 
105
- self._batch.update_many(updates)
106
-
107
- return [self.formatter.dump(item) for item in updates]
105
+ return [self.formatter.dump(item) for item in self._batch.renew(updates)]
108
106
 
109
107
  def replace_one(self, item: RawItem) -> RawItem:
110
108
  self.repository.update(self.formatter.load(item))
@@ -112,9 +110,9 @@ class RestfulRepository(RestfulService, Generic[ItemT]):
112
110
  return item
113
111
 
114
112
  def replace_many(self, items: RawCollection) -> RawCollection:
115
- self._batch.update_many([self.formatter.load(item) for item in items])
113
+ updated = self._batch.renew([self.formatter.load(item) for item in items])
116
114
 
117
- return items
115
+ return [self.formatter.dump(item) for item in updated]
118
116
 
119
117
  def delete_one(self, item_id: str) -> None:
120
118
  self.repository.delete(item_id)
@@ -1,6 +1,9 @@
1
- from collections.abc import Iterable, Iterator
1
+ from collections.abc import Container, Iterable, Iterator
2
+ from contextlib import suppress
2
3
  from dataclasses import dataclass, field
3
4
 
5
+ from apexdevkit.error import DoesNotExistError, ExistsError
6
+
4
7
  from .interface import ItemT, Repository
5
8
 
6
9
 
@@ -55,9 +58,20 @@ class RepositoryDecorator(Repository[ItemT]): # pragma: no cover
55
58
 
56
59
  @dataclass(frozen=True, kw_only=True)
57
60
  class BruteForceBatch(RepositoryDecorator[ItemT]):
58
- def create_many(self, items: Iterable[ItemT]) -> Iterable[ItemT]:
59
- return [self.inner.create(item) for item in items]
60
-
61
- def update_many(self, items: Iterable[ItemT]) -> None:
62
- for item in items:
63
- self.inner.update(item)
61
+ def load(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
62
+ for item in list(source):
63
+ with suppress(ExistsError):
64
+ yield self.inner.create(item)
65
+
66
+ def prune(self, source: Container[ItemT]) -> Iterable[ItemT]:
67
+ for item in list(self.inner):
68
+ if item not in source:
69
+ with suppress(DoesNotExistError):
70
+ self.inner.delete(item.id)
71
+ yield item
72
+
73
+ def renew(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
74
+ for item in list(source):
75
+ with suppress(DoesNotExistError):
76
+ self.inner.update(item)
77
+ yield item
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Callable, Collection, Iterable
3
+ from collections.abc import Callable, Collection, Container, Iterable
4
4
  from dataclasses import dataclass, field
5
5
  from typing import Protocol, TypeVar
6
6
  from uuid import uuid4
@@ -35,8 +35,11 @@ class Repository(Collection[ItemT], Protocol[ItemT]): # pragma: no cover
35
35
 
36
36
 
37
37
  class BatchRepository(Repository[ItemT], Protocol[ItemT]): # pragma: no cover
38
- def create_many(self, items: Iterable[ItemT]) -> Iterable[ItemT]:
38
+ def load(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
39
39
  pass
40
40
 
41
- def update_many(self, items: Iterable[ItemT]) -> None:
41
+ def prune(self, source: Container[ItemT]) -> Iterable[ItemT]:
42
+ pass
43
+
44
+ def renew(self, source: Iterable[ItemT]) -> Iterable[ItemT]:
42
45
  pass
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.29.3"
3
+ version = "1.30.1"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,54 +0,0 @@
1
- import os
2
- from threading import Lock
3
- from time import time
4
-
5
-
6
- class ApexID:
7
- last_timestamp: int = -1
8
- sequence: int = 0
9
- lock: Lock = Lock()
10
-
11
- _metadata_bitmask: int = 0x0FFF
12
- _sequence_bitmask: int = 0x03FF
13
- _timestamp_bitmask: int = 0x03FFFFFFFFFF
14
-
15
- @classmethod
16
- def id(cls) -> int:
17
- """
18
- Generates a unique identifier with the following structure
19
- from most significant to least significant:
20
- 1 bit reserved
21
- 41 bits for unix timestamp (millisecond precision)
22
- 12 bits for metadata
23
- 10 bits for sequence
24
- """
25
- with cls.lock:
26
- current_timestamp = cls._get_timestamp()
27
- if cls.last_timestamp == current_timestamp:
28
- cls.sequence += 1
29
- else:
30
- cls.sequence = 0
31
-
32
- if cls.sequence > cls._sequence_bitmask:
33
- raise DuplicateIDError("Duplicate ID Generated")
34
-
35
- cls.last_timestamp = current_timestamp
36
-
37
- return (
38
- (0 << 63)
39
- | ((cls.last_timestamp & cls._timestamp_bitmask) << 22)
40
- | ((cls._metadata() & cls._metadata_bitmask) << 10)
41
- | (cls.sequence & cls._sequence_bitmask)
42
- )
43
-
44
- @classmethod
45
- def _get_timestamp(cls) -> int:
46
- return int(time() * 1000)
47
-
48
- @classmethod
49
- def _metadata(cls) -> int:
50
- return int(os.getenv("APEX_ID_METADATA", "0"))
51
-
52
-
53
- class DuplicateIDError(Exception):
54
- pass
@@ -1,48 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Iterable, Iterator
4
- from dataclasses import dataclass
5
- from typing import Generic, Protocol, TypeVar
6
-
7
- ItemT = TypeVar("ItemT")
8
-
9
-
10
- @dataclass(frozen=True)
11
- class Sync(Generic[ItemT]):
12
- source: _Source[ItemT]
13
- target: _Target[ItemT]
14
-
15
- def sync(self) -> None:
16
- items = self.source.value_of(list(self.target))
17
- self.target.update_many(list(items))
18
-
19
-
20
- class _Source(Protocol[ItemT]):
21
- def value_of(self, items: Iterable[ItemT]) -> Iterable[ItemT]:
22
- pass
23
-
24
-
25
- class _Target(Protocol[ItemT]):
26
- def __iter__(self) -> Iterator[ItemT]:
27
- pass
28
-
29
- def update_many(self, items: Iterable[ItemT]) -> None:
30
- pass
31
-
32
-
33
- @dataclass(frozen=True)
34
- class FullSync(Generic[ItemT]):
35
- source: Iterable[ItemT]
36
- target: _FullTarget[ItemT]
37
-
38
- def sync(self) -> None:
39
- items = list(self.source)
40
- self.target.update_many(items)
41
-
42
-
43
- ItemR = TypeVar("ItemR", contravariant=True)
44
-
45
-
46
- class _FullTarget(Protocol[ItemR]):
47
- def update_many(self, items: Iterable[ItemR]) -> None:
48
- pass
File without changes
File without changes