querymodelling 0.0.6__tar.gz → 0.0.8__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 (24) hide show
  1. {querymodelling-0.0.6/querymodelling.egg-info → querymodelling-0.0.8}/PKG-INFO +1 -1
  2. {querymodelling-0.0.6 → querymodelling-0.0.8}/pyproject.toml +1 -1
  3. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/__version__.py +1 -1
  4. querymodelling-0.0.8/querymodelling/redis_om.py +153 -0
  5. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/sql.py +7 -3
  6. {querymodelling-0.0.6 → querymodelling-0.0.8/querymodelling.egg-info}/PKG-INFO +1 -1
  7. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling.egg-info/SOURCES.txt +1 -0
  8. {querymodelling-0.0.6 → querymodelling-0.0.8}/AUTHORS.rst +0 -0
  9. {querymodelling-0.0.6 → querymodelling-0.0.8}/LICENSE +0 -0
  10. {querymodelling-0.0.6 → querymodelling-0.0.8}/README.md +0 -0
  11. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/__helper__.py +0 -0
  12. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/__init__.py +0 -0
  13. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/base.py +0 -0
  14. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/fields.py +0 -0
  15. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/model.py +0 -0
  16. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling/pydantic.py +0 -0
  17. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling.egg-info/dependency_links.txt +0 -0
  18. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling.egg-info/requires.txt +0 -0
  19. {querymodelling-0.0.6 → querymodelling-0.0.8}/querymodelling.egg-info/top_level.txt +0 -0
  20. {querymodelling-0.0.6 → querymodelling-0.0.8}/setup.cfg +0 -0
  21. {querymodelling-0.0.6 → querymodelling-0.0.8}/setup.py +0 -0
  22. {querymodelling-0.0.6 → querymodelling-0.0.8}/tests/__init__.py +0 -0
  23. {querymodelling-0.0.6 → querymodelling-0.0.8}/tests/__main__.py +0 -0
  24. {querymodelling-0.0.6 → querymodelling-0.0.8}/tests/basic_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: querymodelling
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Summary: build consistent api query models for fastapi
5
5
  Author: George Haddad
6
6
  Author-email: George Haddad <georgeh87@live.de>
@@ -11,7 +11,7 @@ testpaths = ["tests"]
11
11
 
12
12
  [project]
13
13
  name = "querymodelling"
14
- version = "0.0.6"
14
+ version = "0.0.8"
15
15
  description = "build consistent api query models for fastapi"
16
16
  readme = "README.md"
17
17
  requires-python = ">=3.11"
@@ -1,7 +1,7 @@
1
1
  __title__ = "querymodelling"
2
2
  __description__ = ""
3
3
  __url__ = "https://querymodelling.readthedocs.io"
4
- __version__ = "0.0.6"
4
+ __version__ = "0.0.8"
5
5
  __build__ = 0x023100
6
6
  __author__ = "George Haddad"
7
7
  __author_email__ = "georgeh87@live.de"
@@ -0,0 +1,153 @@
1
+ from datetime import datetime
2
+ from typing import TypeVar, Sequence, Type, Callable, ParamSpec
3
+
4
+ from .__helper__ import is_enum
5
+ from .base import get_functions, DefaultSort
6
+ from .fields import QueryField, SortField
7
+ from .model import PageQuery
8
+
9
+
10
+ T = TypeVar("T")
11
+ PK = ParamSpec("PK")
12
+ Q = TypeVar("Q", bound=PageQuery)
13
+
14
+ def sortable_by(field, field_name):
15
+ def wrapper(order: DefaultSort):
16
+ if order == "desc":
17
+ return f"-{field_name}"
18
+ if order == "asc":
19
+ return field_name
20
+ return wrapper
21
+
22
+ def create_statement(
23
+ query: Q,
24
+ t: Type[T]
25
+ ):
26
+ search_clause = get_functions(query, "query")
27
+ order_clause = get_functions(query, "sort")
28
+ statement = t.find(*search_clause)
29
+ if order_clause:
30
+ statement = statement.sort_by(*order_clause)
31
+ return statement
32
+
33
+ def retrieve_paged_entries(
34
+ query: Q,
35
+ t: Type[T],
36
+ ) -> tuple[int, Sequence[T]]:
37
+ statement = create_statement(query, t)
38
+
39
+ statement = statement.copy(
40
+ offset=query.page * query.size, limit=query.size)
41
+
42
+ entries = statement.execute(exhaust_results=False)
43
+ total_elements = statement.count()
44
+
45
+ return total_elements, entries
46
+
47
+ def retrieve_entries(
48
+ query: Q,
49
+ t: Type[T]
50
+ ) -> tuple[int, Sequence[T]]:
51
+ statement = create_statement(query, t)
52
+ return statement.all()
53
+
54
+ def create_query_fields(
55
+ base_field: any,
56
+ field_name: str,
57
+ annotation: any,
58
+ operator_mapping: dict[str, Callable],
59
+ json_schema_extra: dict
60
+ ):
61
+ for operator, operator_function in operator_mapping.items():
62
+ if operator is None:
63
+ name = field_name
64
+ else:
65
+ name = f"{field_name}_{operator}"
66
+ yield (
67
+ name,
68
+ QueryField(base_field)(
69
+ operator_function,
70
+ default=None,
71
+ json_schema_extra=json_schema_extra | {
72
+ "query.operator": operator
73
+ }
74
+ ),
75
+ annotation
76
+ )
77
+
78
+ def create_callback(
79
+ base_field,
80
+ copy_field_properties: list[str] = None,
81
+ schema_extra: dict = None
82
+ ):
83
+ def auto_create_callback(
84
+ source_type: type,
85
+ field_name: str,
86
+ field,
87
+ field_info,
88
+ annotation
89
+ ):
90
+ if copy_field_properties is None and schema_extra is None:
91
+ json_schema_extra = field_info.json_schema_extra
92
+ json_schema_extra = schema_extra or {}
93
+ if copy_field_properties is not None:
94
+ for property_name in copy_field_properties:
95
+ json_schema_extra[property_name] = field_info[
96
+ property_name]
97
+
98
+ json_schema_extra = json_schema_extra | {
99
+ "query.backend": "redis",
100
+ "query.field": field_name
101
+ }
102
+
103
+ if annotation == str:
104
+ operator_mapping = {
105
+ None: lambda value: field == value,
106
+ "not": lambda value: field != value,
107
+ "startswith": lambda value: field.startswith(value),
108
+ "endswith": lambda value: field.endswith(value),
109
+ "contains": lambda value: field % value
110
+ }
111
+ yield from create_query_fields(
112
+ base_field,
113
+ field_name,
114
+ annotation,
115
+ operator_mapping,
116
+ json_schema_extra
117
+ )
118
+ elif annotation in (datetime, int):
119
+ operator_mapping = {
120
+ None: lambda value: field == value,
121
+ "from": lambda value: field >= value,
122
+ "to": lambda value: field <= value,
123
+ "not": lambda value: field != value
124
+ }
125
+ yield from create_query_fields(
126
+ base_field,
127
+ field_name,
128
+ annotation,
129
+ operator_mapping,
130
+ json_schema_extra
131
+ )
132
+ elif is_enum(annotation):
133
+ operator_mapping = {
134
+ None: lambda value: field == value,
135
+ "not": lambda value: field != value
136
+ }
137
+ yield from create_query_fields(
138
+ base_field,
139
+ field_name,
140
+ annotation,
141
+ operator_mapping,
142
+ json_schema_extra
143
+ )
144
+ yield (
145
+ f"sort_{field_name}",
146
+ SortField(base_field)(
147
+ sortable_by(source_type.__dict__[field_name], field_name),
148
+ default=None,
149
+ json_schema_extra=json_schema_extra
150
+ ),
151
+ DefaultSort
152
+ )
153
+ return auto_create_callback
@@ -88,14 +88,15 @@ def create_query_fields(
88
88
  def create_callback(
89
89
  base_field,
90
90
  copy_field_properties: list[str] = None,
91
- schema_extra: dict = None
91
+ schema_extra: dict = None,
92
+ use_alias_reference: bool = True,
92
93
  ):
93
94
  def auto_create_callback(
94
95
  source_type: type,
95
96
  field_name: str,
96
97
  field,
97
98
  field_info,
98
- annotation
99
+ annotation,
99
100
  ):
100
101
  if copy_field_properties is None and schema_extra is None:
101
102
  json_schema_extra = field_info.json_schema_extra
@@ -107,7 +108,10 @@ def create_callback(
107
108
 
108
109
  json_schema_extra = json_schema_extra | {
109
110
  "query.backend": "sql",
110
- "query.field": field_name,
111
+ "query.field": (
112
+ (field_info.alias or field_name)
113
+ if use_alias_reference else field_name
114
+ ),
111
115
  }
112
116
 
113
117
  if annotation == str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: querymodelling
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Summary: build consistent api query models for fastapi
5
5
  Author: George Haddad
6
6
  Author-email: George Haddad <georgeh87@live.de>
@@ -10,6 +10,7 @@ querymodelling/base.py
10
10
  querymodelling/fields.py
11
11
  querymodelling/model.py
12
12
  querymodelling/pydantic.py
13
+ querymodelling/redis_om.py
13
14
  querymodelling/sql.py
14
15
  querymodelling.egg-info/PKG-INFO
15
16
  querymodelling.egg-info/SOURCES.txt
File without changes
File without changes
File without changes
File without changes