alpha-python 0.1.0__py3-none-any.whl

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 (62) hide show
  1. alpha/__init__.py +0 -0
  2. alpha/adapters/__init__.py +0 -0
  3. alpha/adapters/sqla_unit_of_work.py +120 -0
  4. alpha/domain/__init__.py +0 -0
  5. alpha/domain/models/__init__.py +0 -0
  6. alpha/domain/models/base_model.py +25 -0
  7. alpha/encoder.py +62 -0
  8. alpha/exceptions.py +99 -0
  9. alpha/factories/__init__.py +0 -0
  10. alpha/factories/_type_conversion_matrix.py +233 -0
  11. alpha/factories/_type_mapping.py +29 -0
  12. alpha/factories/class_factories.py +496 -0
  13. alpha/factories/default_field_factory.py +50 -0
  14. alpha/factories/field_iterator.py +188 -0
  15. alpha/factories/logging_handler_factory.py +86 -0
  16. alpha/factories/model_class_factory.py +176 -0
  17. alpha/factories/models/__init__.py +0 -0
  18. alpha/factories/models/factory_classes.py +20 -0
  19. alpha/factories/request_factory.py +211 -0
  20. alpha/factories/response_factory.py +186 -0
  21. alpha/factories/type_factories.py +204 -0
  22. alpha/infra/__init__.py +0 -0
  23. alpha/infra/database/__init__.py +0 -0
  24. alpha/infra/database/sql_alchemy_database.py +159 -0
  25. alpha/infra/database/sql_alchemy_view.py +48 -0
  26. alpha/infra/models/__init__.py +0 -0
  27. alpha/infra/models/filter_operators.py +98 -0
  28. alpha/infra/models/json_patch.py +21 -0
  29. alpha/infra/models/order_by.py +69 -0
  30. alpha/infra/models/query_clause.py +45 -0
  31. alpha/infra/models/search_filter.py +586 -0
  32. alpha/interfaces/__init__.py +0 -0
  33. alpha/interfaces/attrs_instance.py +10 -0
  34. alpha/interfaces/dataclass_instance.py +11 -0
  35. alpha/interfaces/factories.py +102 -0
  36. alpha/interfaces/openapi_model.py +21 -0
  37. alpha/interfaces/patchable.py +8 -0
  38. alpha/interfaces/sql_database.py +36 -0
  39. alpha/interfaces/sql_mapper.py +23 -0
  40. alpha/interfaces/sql_repository.py +380 -0
  41. alpha/interfaces/token_factory.py +56 -0
  42. alpha/interfaces/unit_of_work.py +53 -0
  43. alpha/interfaces/updateable.py +7 -0
  44. alpha/py.typed +0 -0
  45. alpha/repositories/__init__.py +0 -0
  46. alpha/repositories/default_sql_repository.py +679 -0
  47. alpha/repositories/models/__init__.py +0 -0
  48. alpha/repositories/models/repository_model.py +16 -0
  49. alpha/services/__init__.py +0 -0
  50. alpha/services/authentication_service.py +71 -0
  51. alpha/utils/__init__.py +0 -0
  52. alpha/utils/_http_codes.py +148 -0
  53. alpha/utils/is_attrs.py +18 -0
  54. alpha/utils/logging_configurator.py +133 -0
  55. alpha/utils/logging_level_checker.py +26 -0
  56. alpha/utils/response_object.py +26 -0
  57. alpha/utils/version_check.py +17 -0
  58. alpha_python-0.1.0.dist-info/METADATA +22 -0
  59. alpha_python-0.1.0.dist-info/RECORD +62 -0
  60. alpha_python-0.1.0.dist-info/WHEEL +5 -0
  61. alpha_python-0.1.0.dist-info/licenses/LICENSE +21 -0
  62. alpha_python-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ import datetime
2
+ from contextlib import suppress
3
+
4
+ import jsonpatch
5
+
6
+
7
+ class JsonPatch(jsonpatch.JsonPatch):
8
+ def __init__(self, *args, **kwargs):
9
+ super().__init__(*args, **kwargs)
10
+ self.update_dates()
11
+
12
+ def update_dates(self) -> None:
13
+ """Post init to ensure that if a date can be formated to isoformat this
14
+ is done.
15
+ """
16
+ for update in self:
17
+ if isinstance(update['value'], str):
18
+ with suppress(ValueError):
19
+ update['value'] = datetime.datetime.fromisoformat(
20
+ update['value']
21
+ )
@@ -0,0 +1,69 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum, auto
3
+ from typing import Any
4
+
5
+ from sqlalchemy import BinaryExpression
6
+ from sqlalchemy.orm import Query
7
+ from sqlalchemy.orm.attributes import InstrumentedAttribute
8
+
9
+ from alpha.infra.models.query_clause import QueryClause
10
+
11
+
12
+ class Order(Enum):
13
+ ASC = auto()
14
+ DESC = auto()
15
+
16
+
17
+ @dataclass
18
+ class OrderBy(QueryClause):
19
+ field: str | InstrumentedAttribute[Any] = ""
20
+ order: Order = Order.ASC
21
+
22
+ def __post_init__(self) -> None:
23
+ super().__post_init__()
24
+ self.__class__ = self._get_filter_class()
25
+
26
+ def _get_filter_class(self):
27
+ match self.order:
28
+ case Order.ASC:
29
+ return AscendingOrder
30
+ case Order.DESC:
31
+ return DescendingOrder
32
+
33
+
34
+ class AscendingOrder(OrderBy):
35
+ @property
36
+ def filter_statement(self) -> BinaryExpression[Any]:
37
+ """Returns a lesser then filter statement
38
+
39
+ Returns
40
+ -------
41
+ Filter statement
42
+ """
43
+ if self._instrumented_attr:
44
+ return self._instrumented_attr.asc()
45
+ self._raise_instrumented_attr_exception()
46
+
47
+ def query_clause(self, query: Query[Any]):
48
+ if self._instrumented_attr:
49
+ return query.order_by(self._instrumented_attr.asc())
50
+ self._raise_instrumented_attr_exception()
51
+
52
+
53
+ class DescendingOrder(OrderBy):
54
+ @property
55
+ def filter_statement(self) -> BinaryExpression[Any]:
56
+ """Returns a lesser then filter statement
57
+
58
+ Returns
59
+ -------
60
+ Filter statement
61
+ """
62
+ if self._instrumented_attr:
63
+ return self._instrumented_attr.desc()
64
+ self._raise_instrumented_attr_exception()
65
+
66
+ def query_clause(self, query: Query[Any]):
67
+ if self._instrumented_attr:
68
+ return query.order_by(self._instrumented_attr.desc())
69
+ self._raise_instrumented_attr_exception()
@@ -0,0 +1,45 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any
3
+
4
+ from sqlalchemy.orm.attributes import InstrumentedAttribute
5
+ from sqlalchemy.orm.query import Query
6
+
7
+ from alpha import exceptions
8
+ from alpha.domain.models.base_model import BaseDomainModel
9
+
10
+
11
+ @dataclass
12
+ class QueryClause:
13
+ field: str | InstrumentedAttribute[str]
14
+ _domain_model: BaseDomainModel | None = None
15
+ _instrumented_attr: InstrumentedAttribute[Any] | None = None
16
+
17
+ def __post_init__(self) -> None:
18
+ # Get key name if field is an instrumented attribute
19
+ if isinstance(self.field, InstrumentedAttribute):
20
+ self._instrumented_attr = self.field
21
+ self.field = self.field.key
22
+
23
+ # Try to get the instrumented attribute if only a field name is given
24
+ self.set_domain_model()
25
+
26
+ def query_clause(self, query: Query[Any]) -> Query[Any]:
27
+ raise NotImplementedError
28
+
29
+ def set_domain_model(self, model: BaseDomainModel | None = None):
30
+ self._domain_model = model
31
+
32
+ if not self._instrumented_attr:
33
+ if self._domain_model:
34
+ self._instrumented_attr = getattr(
35
+ self._domain_model, self.field # type: ignore
36
+ )
37
+
38
+ def _raise_instrumented_attr_exception(self):
39
+ raise exceptions.InstrumentedAttributeMissing(
40
+ """
41
+ The 'field' attribute needs to be of an \
42
+ sqlalchemy.orm.InstrumentedAttribute type, or specify the mapped domain model \
43
+ by adding the _domain_model attribute
44
+ """
45
+ )