apexdevkit 1.23.4__tar.gz → 1.23.6__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 (55) hide show
  1. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/PKG-INFO +1 -1
  2. apexdevkit-1.23.6/apexdevkit/date.py +79 -0
  3. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/resource.py +3 -5
  4. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/router.py +4 -1
  5. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/schema.py +13 -0
  6. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/service.py +2 -2
  7. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/pyproject.toml +1 -1
  8. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/LICENSE +0 -0
  9. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/README.md +0 -0
  10. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/__init__.py +0 -0
  11. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/annotation/__init__.py +0 -0
  12. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/annotation/deprecate.py +0 -0
  13. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/environment.py +0 -0
  14. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/error.py +0 -0
  15. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/__init__.py +0 -0
  16. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/builder.py +0 -0
  17. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/dependable.py +0 -0
  18. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/docs.py +0 -0
  19. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/name.py +0 -0
  20. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/request.py +0 -0
  21. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fastapi/response.py +0 -0
  22. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/fluent.py +0 -0
  23. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/formatter.py +0 -0
  24. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/__init__.py +0 -0
  25. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/fake.py +0 -0
  26. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/fluent.py +0 -0
  27. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/httpx/__init__.py +0 -0
  28. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/httpx/client.py +0 -0
  29. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/httpx/hooks.py +0 -0
  30. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/json.py +0 -0
  31. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/http/url.py +0 -0
  32. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/id.py +0 -0
  33. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/key_fn.py +0 -0
  34. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/py.typed +0 -0
  35. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/query/__init__.py +0 -0
  36. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/query/generator.py +0 -0
  37. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/query/query.py +0 -0
  38. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/__init__.py +0 -0
  39. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/base.py +0 -0
  40. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/connector.py +0 -0
  41. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/database.py +0 -0
  42. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/decorator.py +0 -0
  43. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/in_memory.py +0 -0
  44. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/interface.py +0 -0
  45. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/mssql.py +0 -0
  46. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/repository.py +0 -0
  47. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/sql.py +0 -0
  48. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/repository/sqlite.py +0 -0
  49. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/server.py +0 -0
  50. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/synchronization.py +0 -0
  51. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/testing/__init__.py +0 -0
  52. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/testing/database.py +0 -0
  53. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/testing/fake.py +0 -0
  54. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/testing/rest.py +0 -0
  55. {apexdevkit-1.23.4 → apexdevkit-1.23.6}/apexdevkit/value.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: apexdevkit
3
- Version: 1.23.4
3
+ Version: 1.23.6
4
4
  Summary: Apex Development Tools for python.
5
5
  Author: Apex Dev
6
6
  Author-email: dev@apex.ge
@@ -0,0 +1,79 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import UTC, datetime
5
+ from zoneinfo import ZoneInfo
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class DateTime:
10
+ timestamp_ms: int
11
+
12
+ # Date in format of "yyyy-mm-dd"
13
+ def as_date(self, time_zone: ZoneInfo | None = None) -> str:
14
+ if time_zone is None:
15
+ time_zone = ZoneInfo("UTC")
16
+
17
+ dt = datetime.fromtimestamp(self.as_timestamp(), tz=UTC)
18
+ local_dt = dt.astimezone(time_zone)
19
+ return local_dt.strftime("%Y-%m-%d")
20
+
21
+ # Date in format of "yyyy-mm-ddTHH:MM:SS"
22
+ def as_date_time(self, time_zone: ZoneInfo | None = None) -> str:
23
+ if time_zone is None:
24
+ time_zone = ZoneInfo("UTC")
25
+
26
+ dt = datetime.fromtimestamp(self.as_timestamp(), tz=UTC)
27
+ local_dt = dt.astimezone(time_zone)
28
+ return local_dt.strftime("%Y-%m-%dT%H:%M:%S")
29
+
30
+ def as_timestamp(self) -> float:
31
+ return float(self.timestamp_ms) / 1000.0
32
+
33
+ def as_timestamp_ms(self) -> int:
34
+ return self.timestamp_ms
35
+
36
+ # Date in format of "yyyy-mm-dd"
37
+ @classmethod
38
+ def from_date(cls, date: str, time_zone: ZoneInfo | None = None) -> DateTime:
39
+ if time_zone is None:
40
+ time_zone = ZoneInfo("UTC")
41
+
42
+ try:
43
+ dt = datetime.strptime(date, "%Y-%m-%d")
44
+ dt = dt.replace(tzinfo=time_zone)
45
+ timestamp_ms = int(dt.timestamp() * 1000)
46
+ return cls(timestamp_ms=timestamp_ms)
47
+
48
+ except ValueError as e:
49
+ raise ValueError(
50
+ f"Invalid date format: '{date}'. Expected 'yyyy-mm-dd'."
51
+ ) from e
52
+
53
+ # Date in format of "yyyy-mm-ddTHH:MM:SS"
54
+ @classmethod
55
+ def from_date_time(
56
+ cls, date_time: str, time_zone: ZoneInfo | None = None
57
+ ) -> DateTime:
58
+ if time_zone is None:
59
+ time_zone = ZoneInfo("UTC")
60
+
61
+ try:
62
+ dt = datetime.strptime(date_time, "%Y-%m-%dT%H:%M:%S")
63
+ dt = dt.replace(tzinfo=time_zone)
64
+ timestamp_ms = int(dt.timestamp() * 1000)
65
+ return cls(timestamp_ms=timestamp_ms)
66
+ except ValueError as e:
67
+ raise ValueError(
68
+ f"Invalid datetime format: '{date_time}'."
69
+ f" Expected 'yyyy-mm-ddTHH:MM:SS'."
70
+ ) from e
71
+
72
+ @classmethod
73
+ def from_timestamp(cls, timestamp: float) -> DateTime:
74
+ timestamp_ms = int(timestamp * 1000)
75
+ return cls(timestamp_ms=timestamp_ms)
76
+
77
+ @classmethod
78
+ def from_timestamp_ms(cls, timestamp_ms: int) -> DateTime:
79
+ return cls(timestamp_ms=timestamp_ms)
@@ -79,12 +79,10 @@ class RestfulResource:
79
79
 
80
80
  return endpoint
81
81
 
82
- def filter_with(self, Service) -> _Endpoint: # type: ignore
83
- def endpoint(service: Service, options: _QueryOptions) -> _Response:
82
+ def filter_with(self, Service, QueryOptions) -> _Endpoint: # type: ignore
83
+ def endpoint(service: Service, options: QueryOptions) -> _Response:
84
84
  try:
85
- return self.response.found_many(
86
- list(service.filter_with(options.to_query_options()))
87
- )
85
+ return self.response.found_many(list(service.filter_with(options)))
88
86
  except ForbiddenError as e:
89
87
  return JSONResponse(self.response.forbidden(e), 403)
90
88
 
@@ -171,7 +171,10 @@ class RestfulRouter:
171
171
  ) -> Self:
172
172
  self.router.add_api_route(
173
173
  "/filter",
174
- self.resource.filter_with(Service=self._resolve(dependency)),
174
+ self.resource.filter_with(
175
+ Service=self._resolve(dependency),
176
+ QueryOptions=Annotated[RawItem, Depends(self.schema.for_filters())],
177
+ ),
175
178
  methods=["POST"],
176
179
  status_code=200,
177
180
  responses={},
@@ -8,6 +8,7 @@ from pydantic import BaseModel, create_model
8
8
 
9
9
  from apexdevkit.fastapi.name import RestfulName
10
10
  from apexdevkit.fluent import FluentDict
11
+ from apexdevkit.http import JsonDict
11
12
 
12
13
 
13
14
  class SchemaFields(ABC):
@@ -20,6 +21,9 @@ class SchemaFields(ABC):
20
21
  def editable(self) -> FluentDict[type]:
21
22
  return self.readable().drop("id")
22
23
 
24
+ def filters(self) -> FluentDict[type]:
25
+ return JsonDict()
26
+
23
27
  @abstractmethod
24
28
  def readable(self) -> FluentDict[type]: # pragma: no cover
25
29
  pass
@@ -38,6 +42,7 @@ class RestfulSchema:
38
42
  update_many_item = self._schema_for(
39
43
  "UpdateManyItem", self.fields.editable().merge(self.fields.id())
40
44
  )
45
+ self._schema_for("Filter", self.fields.filters())
41
46
 
42
47
  self._schema_for("Item", {self.name.singular: schema})
43
48
  self._schema_for("Collection", {self.name.plural: list[schema], "count": int})
@@ -130,6 +135,14 @@ class RestfulSchema:
130
135
 
131
136
  return _
132
137
 
138
+ def for_filters(self) -> Callable[[BaseModel], dict[str, Any]]:
139
+ schema = self.schemas["Filter"]
140
+
141
+ def _(request: schema) -> dict[str, Any]:
142
+ return request.model_dump()
143
+
144
+ return _
145
+
133
146
 
134
147
  @dataclass(frozen=True)
135
148
  class Schema:
@@ -6,7 +6,7 @@ from functools import cached_property
6
6
  from typing import Any, Generic, TypeVar
7
7
 
8
8
  from apexdevkit.formatter import Formatter
9
- from apexdevkit.query.query import FooterOptions, QueryOptions, Summary
9
+ from apexdevkit.query.query import FooterOptions, Summary
10
10
  from apexdevkit.repository.decorator import BruteForceBatch
11
11
  from apexdevkit.repository.interface import Repository
12
12
 
@@ -35,7 +35,7 @@ class RestfulService: # pragma: no cover
35
35
  def read_many(self, **params: Any) -> RawCollection:
36
36
  raise NotImplementedError(self.read_many.__name__)
37
37
 
38
- def filter_with(self, options: QueryOptions) -> RawCollection:
38
+ def filter_with(self, options: RawItem) -> RawCollection:
39
39
  raise NotImplementedError(self.filter_with.__name__)
40
40
 
41
41
  def read_all(self) -> RawCollection:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.23.4"
3
+ version = "1.23.6"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
File without changes
File without changes