alpha-python 0.7.2__tar.gz → 0.7.4__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 (158) hide show
  1. {alpha_python-0.7.2 → alpha_python-0.7.4}/PKG-INFO +2 -2
  2. {alpha_python-0.7.2 → alpha_python-0.7.4}/pyproject.toml +2 -2
  3. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/adapters/rest_api_unit_of_work.py +14 -10
  4. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/group.py +3 -3
  5. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/user.py +4 -4
  6. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/request_factory.py +10 -0
  7. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/controller.mustache +1 -0
  8. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/api_repository.py +21 -0
  9. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/sql_repository.py +13 -2
  10. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/mixins/user_lifecycle.py +11 -11
  11. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/models/identity.py +5 -3
  12. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/refresh/database_repository.py +2 -2
  13. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/request_headers.py +50 -2
  14. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/PKG-INFO +2 -2
  15. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/requires.txt +1 -1
  16. {alpha_python-0.7.2 → alpha_python-0.7.4}/LICENSE +0 -0
  17. {alpha_python-0.7.2 → alpha_python-0.7.4}/README.md +0 -0
  18. {alpha_python-0.7.2 → alpha_python-0.7.4}/setup.cfg +0 -0
  19. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/__init__.py +0 -0
  20. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/adapters/__init__.py +0 -0
  21. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/adapters/sqla_unit_of_work.py +0 -0
  22. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/cli.py +0 -0
  23. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/containers/__init__.py +0 -0
  24. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/containers/container.py +0 -0
  25. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/__init__.py +0 -0
  26. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/__init__.py +0 -0
  27. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/base_model.py +0 -0
  28. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/life_cycle_base.py +0 -0
  29. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/domain/models/role.py +0 -0
  30. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/encoder.py +0 -0
  31. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/exceptions.py +0 -0
  32. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/__init__.py +0 -0
  33. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/_type_conversion_matrix.py +0 -0
  34. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/_type_mapping.py +0 -0
  35. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/class_factories.py +0 -0
  36. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/default_field_factory.py +0 -0
  37. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/field_iterator.py +0 -0
  38. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/jwt_factory.py +0 -0
  39. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/logging_handler_factory.py +0 -0
  40. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/model_class_factory.py +0 -0
  41. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/models/__init__.py +0 -0
  42. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/models/factory_classes.py +0 -0
  43. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/password_factory.py +0 -0
  44. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/response_factory.py +0 -0
  45. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/factories/type_factories.py +0 -0
  46. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/__init__.py +0 -0
  47. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/api_generate_handler.py +0 -0
  48. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/api_run_handler.py +0 -0
  49. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/base_handler.py +0 -0
  50. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/gen-code.sh +0 -0
  51. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/models/__init__.py +0 -0
  52. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/models/argument.py +0 -0
  53. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/models/command.py +0 -0
  54. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/models/section.py +0 -0
  55. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/models/subparser.py +0 -0
  56. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/run-api.sh +0 -0
  57. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/__init__.py +0 -0
  58. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/Dockerfile.mustache +0 -0
  59. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/README.mustache +0 -0
  60. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/__init__model.mustache +0 -0
  61. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/__init__test.mustache +0 -0
  62. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/__main__.mustache +0 -0
  63. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/base_model.mustache +0 -0
  64. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/controller_test.mustache +0 -0
  65. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/dockerignore.mustache +0 -0
  66. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/encoder.mustache +0 -0
  67. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/git_push.sh.mustache +0 -0
  68. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/gitignore.mustache +0 -0
  69. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/model.mustache +0 -0
  70. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/openapi.mustache +0 -0
  71. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/param_type.mustache +0 -0
  72. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/requirements.mustache +0 -0
  73. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/security_controller_.mustache +0 -0
  74. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/setup.mustache +0 -0
  75. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/test-requirements.mustache +0 -0
  76. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/tox.mustache +0 -0
  77. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/travis.mustache +0 -0
  78. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/typing_utils.mustache +0 -0
  79. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/handlers/templates/python-flask/util.mustache +0 -0
  80. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/__init__.py +0 -0
  81. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/connectors/__init__.py +0 -0
  82. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/connectors/ldap_connector.py +0 -0
  83. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/connectors/oidc_connector.py +0 -0
  84. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/connectors/sql_alchemy.py +0 -0
  85. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/databases/__init__.py +0 -0
  86. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/databases/sql_alchemy.py +0 -0
  87. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/__init__.py +0 -0
  88. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/filter_operators.py +0 -0
  89. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/json_patch.py +0 -0
  90. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/order_by.py +0 -0
  91. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/query_clause.py +0 -0
  92. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/infra/models/search_filter.py +0 -0
  93. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/__init__.py +0 -0
  94. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/attrs_instance.py +0 -0
  95. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/dataclass_instance.py +0 -0
  96. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/factories.py +0 -0
  97. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/handler.py +0 -0
  98. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/http_client.py +0 -0
  99. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/openapi_model.py +0 -0
  100. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/patchable.py +0 -0
  101. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/providers.py +0 -0
  102. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/pydantic_instance.py +0 -0
  103. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/refresh_repository.py +0 -0
  104. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/sql_database.py +0 -0
  105. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/sql_mapper.py +0 -0
  106. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/token_factory.py +0 -0
  107. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/unit_of_work.py +0 -0
  108. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/interfaces/updatable.py +0 -0
  109. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/mixins/__init__.py +0 -0
  110. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/mixins/group_lifecycle.py +0 -0
  111. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/mixins/jwt_provider.py +0 -0
  112. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/__init__.py +0 -0
  113. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/api_key_provider.py +0 -0
  114. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/database_provider.py +0 -0
  115. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/ldap_provider.py +0 -0
  116. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/models/__init__.py +0 -0
  117. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/models/credentials.py +0 -0
  118. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/models/token.py +0 -0
  119. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/providers/oidc_provider.py +0 -0
  120. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/py.typed +0 -0
  121. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/__init__.py +0 -0
  122. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/models/__init__.py +0 -0
  123. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/models/repository_model.py +0 -0
  124. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/refresh/__init__.py +0 -0
  125. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/refresh/cache_repository.py +0 -0
  126. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/refresh/file_repository.py +0 -0
  127. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/refresh/memory_repository.py +0 -0
  128. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/rest_api_repository.py +0 -0
  129. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/repositories/sql_alchemy_repository.py +0 -0
  130. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/services/__init__.py +0 -0
  131. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/services/authentication_service.py +0 -0
  132. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/services/models/__init__.py +0 -0
  133. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/services/models/cookie.py +0 -0
  134. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/services/user_lifecycle_management.py +0 -0
  135. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/__init__.py +0 -0
  136. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/_http_codes.py +0 -0
  137. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/cookie.py +0 -0
  138. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/is_attrs.py +0 -0
  139. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/is_pydantic.py +0 -0
  140. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/logging_configurator.py +0 -0
  141. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/logging_level_checker.py +0 -0
  142. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/__init__.py +0 -0
  143. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/container.py +0 -0
  144. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/exceptions.py +0 -0
  145. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/models.py +0 -0
  146. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/orm.py +0 -0
  147. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/response.py +0 -0
  148. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/openapi_test/service.py +0 -0
  149. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/response_object.py +0 -0
  150. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/secret_generator.py +0 -0
  151. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/verify_identity.py +0 -0
  152. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha/utils/version_checker.py +0 -0
  153. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/SOURCES.txt +0 -0
  154. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/dependency_links.txt +0 -0
  155. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/entry_points.txt +0 -0
  156. {alpha_python-0.7.2 → alpha_python-0.7.4}/src/alpha_python.egg-info/top_level.txt +0 -0
  157. {alpha_python-0.7.2 → alpha_python-0.7.4}/tests/test_cli.py +0 -0
  158. {alpha_python-0.7.2 → alpha_python-0.7.4}/tests/test_encoder.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpha-python
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
5
5
  Author-email: Bart Reijling <bart@reijling.eu>
6
6
  License-Expression: MIT
@@ -34,7 +34,7 @@ Requires-Dist: argon2-cffi>=25.1.0
34
34
  Requires-Dist: httpx
35
35
  Requires-Dist: cryptography
36
36
  Provides-Extra: api-generator
37
- Requires-Dist: openapi-generator-cli==7.23.0; extra == "api-generator"
37
+ Requires-Dist: openapi-generator-cli==7.24.0; extra == "api-generator"
38
38
  Requires-Dist: jdk4py; extra == "api-generator"
39
39
  Provides-Extra: flask
40
40
  Requires-Dist: connexion[swagger-ui]<3,>=2.14.2; extra == "flask"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "alpha-python"
3
- version = "0.7.2"
3
+ version = "0.7.4"
4
4
  description = "Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -94,7 +94,7 @@ dev = [
94
94
 
95
95
  [project.optional-dependencies]
96
96
  api-generator = [
97
- "openapi-generator-cli==7.23.0",
97
+ "openapi-generator-cli==7.24.0",
98
98
  "jdk4py"
99
99
  ]
100
100
  flask = [
@@ -1,9 +1,10 @@
1
1
  """Contains the REST API Unit of Work implementation."""
2
2
 
3
- from typing import Any, TypeVar
3
+ from typing import Any, TypeVar, cast
4
4
 
5
5
  import requests
6
6
 
7
+ from alpha.interfaces.http_client import HTTPClient
7
8
  from alpha.repositories.models.repository_model import RepositoryModel
8
9
 
9
10
 
@@ -22,7 +23,7 @@ class RestApiUnitOfWork:
22
23
  def __init__(
23
24
  self,
24
25
  repos: list[RepositoryModel[Any]],
25
- session: requests.sessions.Session | None = None,
26
+ session: HTTPClient | None = None,
26
27
  ) -> None:
27
28
  """Initialize the Unit of Work with repositories.
28
29
 
@@ -44,11 +45,12 @@ class RestApiUnitOfWork:
44
45
 
45
46
  def __enter__(self: UOW) -> UOW:
46
47
  """Enter the REST API Unit of Work context.
47
- Initializes a :class:`requests.sessions.Session` if one was not
48
- provided and attaches the configured repositories as attributes on the
49
- unit of work instance. Each repository is constructed using the shared
50
- session and its associated configuration, and optionally validated
51
- against a declared interface.
48
+
49
+ Initializes an `HTTPClient` session if one was not provided and attaches
50
+ the configured repositories as attributes on the unit of work instance.
51
+ Each repository is constructed using the shared session and its
52
+ associated configuration, and optionally validated against a declared
53
+ interface.
52
54
 
53
55
  Returns
54
56
  -------
@@ -56,7 +58,9 @@ class RestApiUnitOfWork:
56
58
  The configured :class:`RestApiUnitOfWork` instance to be used
57
59
  within the context manager.
58
60
  """
59
- self._session = self._session or requests.sessions.Session()
61
+ self._session = cast(
62
+ HTTPClient, self._session or requests.sessions.Session()
63
+ )
60
64
 
61
65
  for repo in self._repositories:
62
66
  name: str = repo.name
@@ -100,12 +104,12 @@ class RestApiUnitOfWork:
100
104
  raise NotImplementedError("RestApiUnitOfWork does not support refresh")
101
105
 
102
106
  @property
103
- def session(self) -> requests.sessions.Session | None:
107
+ def session(self) -> HTTPClient | None:
104
108
  """Get the current session.
105
109
 
106
110
  Returns
107
111
  -------
108
- requests.sessions.Session | None
112
+ HTTPClient | None
109
113
  The current session used for API interactions.
110
114
  """
111
115
  return self._session
@@ -1,6 +1,6 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import dataclass, field
2
2
  from datetime import datetime, timezone
3
- from typing import Any, Sequence, cast
3
+ from typing import Any, cast
4
4
  from uuid import UUID
5
5
 
6
6
  from alpha.domain.models.base_model import BaseDomainModel, DomainModel
@@ -36,7 +36,7 @@ class Group(LifeCycleBase, BaseDomainModel):
36
36
  id: UUID | int | str | None = None
37
37
  name: str | None = None
38
38
  description: str | None = None
39
- permissions: Sequence[str] | None = None
39
+ permissions: list[str] = field(default_factory=list) # type: ignore
40
40
  is_active: bool = True
41
41
 
42
42
  def to_dict(self) -> dict[str, Any]:
@@ -1,6 +1,6 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import dataclass, field
2
2
  from datetime import datetime, timezone
3
- from typing import Any, Self, Sequence, cast
3
+ from typing import Any, Self, cast
4
4
  from uuid import UUID
5
5
 
6
6
  from alpha.domain.models.base_model import BaseDomainModel, DomainModel
@@ -67,8 +67,8 @@ class User(LifeCycleBase, BaseDomainModel):
67
67
  email: str | None = None
68
68
  phone: str | None = None
69
69
  display_name: str | None = None
70
- permissions: Sequence[str] | None = None
71
- groups: Sequence[str | Group] | None = None
70
+ permissions: list[str] = field(default_factory=list) # type: ignore
71
+ groups: list[str | Group] = field(default_factory=list) # type: ignore
72
72
  is_active: bool = True
73
73
  admin: bool = False
74
74
 
@@ -25,6 +25,8 @@ from alpha.interfaces.factories import (
25
25
  )
26
26
  from alpha.interfaces.openapi_model import OpenAPIModel
27
27
  from alpha.interfaces.pydantic_instance import PydanticInstance
28
+ from alpha.providers.models.identity import Identity
29
+ from alpha.utils.request_headers import Headers
28
30
 
29
31
 
30
32
  class RequestFactory:
@@ -184,6 +186,8 @@ class RequestFactory:
184
186
  DataclassInstance
185
187
  | AttrsInstance
186
188
  | PydanticInstance
189
+ | Identity
190
+ | Headers
187
191
  | None
188
192
  | OpenAPIModel
189
193
  ):
@@ -202,6 +206,9 @@ class RequestFactory:
202
206
  -------
203
207
  DataclassInstance | AttrsInstance | PydanticInstance | None
204
208
  Dataclass, attrs, or pydantic instance
209
+ Identity | Headers
210
+ If the value is an instance of Identity or Headers, it will be
211
+ returned as is.
205
212
  OpenAPIModel
206
213
  If the `use_model_class_factory` parameter is set to False, the
207
214
  value will be returned as an OpenAPIModel instance.
@@ -211,6 +218,9 @@ class RequestFactory:
211
218
  TypeError
212
219
  The value is not an instance of the OpenAPI (Base)Model
213
220
  """
221
+ if isinstance(value, (Identity, Headers)):
222
+ return value
223
+
214
224
  if not isinstance(value, OpenAPIModel):
215
225
  raise TypeError(f"Unable to map {type(value)} on dataclass model")
216
226
 
@@ -198,6 +198,7 @@ def {{operationId}}(
198
198
  auth_token = headers.auth_token if headers.has_auth_token else None
199
199
  refresh_token = headers.refresh_token
200
200
  api_key = headers.api_key
201
+ cookies = headers.cookies
201
202
 
202
203
  {{#vendorExtensions.x-alpha-factory}}
203
204
  factory = {{vendorExtensions.x-alpha-factory}}
@@ -11,6 +11,27 @@ from alpha.infra.models.json_patch import JsonPatch
11
11
  class ApiRepository(Protocol[DomainModel]):
12
12
  """Repository contract for remote API resources."""
13
13
 
14
+ def request(
15
+ self,
16
+ method: str,
17
+ url: str,
18
+ **kwargs: Any,
19
+ ) -> Any | None:
20
+ """Make a custom API request.
21
+
22
+ Parameters
23
+ ----------
24
+ method
25
+ The HTTP method to use for the request (e.g., 'GET', 'POST',
26
+ 'PATCH', 'PUT', 'DELETE').
27
+ url
28
+ The URL to which the request should be made.
29
+ **kwargs
30
+ Additional parameters to include in the API request, such as
31
+ headers, authentication tokens, or other request options.
32
+ """
33
+ ...
34
+
14
35
  @overload
15
36
  def add(
16
37
  self,
@@ -3,7 +3,14 @@ SQLAlchemy ORM repository operations.
3
3
  """
4
4
 
5
5
  from enum import Enum
6
- from typing import Any, Literal, Protocol, overload, runtime_checkable
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ Any,
9
+ Literal,
10
+ Protocol,
11
+ overload,
12
+ runtime_checkable,
13
+ )
7
14
  from uuid import UUID
8
15
 
9
16
  from sqlalchemy.orm import Session
@@ -12,7 +19,11 @@ from sqlalchemy.orm.attributes import InstrumentedAttribute
12
19
  from alpha.domain.models.base_model import BaseDomainModel, DomainModel
13
20
  from alpha.infra.models.json_patch import JsonPatch
14
21
  from alpha.interfaces.patchable import Patchable
15
- from alpha.interfaces.updatable import Updatable
22
+
23
+ if TYPE_CHECKING:
24
+ from alpha.interfaces.updatable import Updatable
25
+ else:
26
+ Updatable = Any
16
27
 
17
28
 
18
29
  @runtime_checkable
@@ -1,6 +1,6 @@
1
1
  """Contains the UserLifecycleMixin class"""
2
2
 
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Any
4
4
  from uuid import UUID
5
5
 
6
6
  from alpha.exceptions import BadRequestException, NotFoundException
@@ -11,6 +11,8 @@ from alpha.providers.models.identity import Identity
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from alpha.domain.models.user import User
14
+ else:
15
+ User = Any
14
16
 
15
17
 
16
18
  class UserLifecycleMixin:
@@ -20,15 +22,13 @@ class UserLifecycleMixin:
20
22
 
21
23
  uow: UnitOfWork
22
24
  _users_repository_name: str
23
- _user_model: type["User"]
25
+ _user_model: type[User]
24
26
  _password_support: bool
25
27
  _password_factory: PasswordFactory
26
28
  _user_username_attribute: str
27
29
  _user_password_attribute: str
28
30
 
29
- def add_user(
30
- self, user: "User", identity: Identity | None = None
31
- ) -> "User":
31
+ def add_user(self, user: User, identity: Identity | None = None) -> User:
32
32
  """Adds a new user object to the repository
33
33
 
34
34
  Parameters
@@ -79,7 +79,7 @@ class UserLifecycleMixin:
79
79
  self.uow.commit()
80
80
  return user
81
81
 
82
- def get_user(self, user_id: str | int | UUID) -> "User":
82
+ def get_user(self, user_id: str | int | UUID) -> User:
83
83
  """Get an user object by id from the repository
84
84
 
85
85
  Parameters
@@ -110,7 +110,7 @@ class UserLifecycleMixin:
110
110
 
111
111
  return user
112
112
 
113
- def get_users(self) -> list["User"]:
113
+ def get_users(self) -> list[User]:
114
114
  """Gets all user objects from the repository
115
115
 
116
116
  Returns
@@ -119,7 +119,7 @@ class UserLifecycleMixin:
119
119
  A collection of all the user objects
120
120
  """
121
121
  with self.uow:
122
- users: SqlRepository["User"] = getattr(
122
+ users: SqlRepository[User] = getattr(
123
123
  self.uow, self._users_repository_name
124
124
  )
125
125
  result = users.select()
@@ -136,7 +136,7 @@ class UserLifecycleMixin:
136
136
  """
137
137
  user = self.get_user(user_id=user_id)
138
138
  with self.uow:
139
- users: SqlRepository["User"] = getattr(
139
+ users: SqlRepository[User] = getattr(
140
140
  self.uow, self._users_repository_name
141
141
  )
142
142
 
@@ -146,9 +146,9 @@ class UserLifecycleMixin:
146
146
  def update_user(
147
147
  self,
148
148
  user_id: str | int | UUID,
149
- user: "User",
149
+ user: User,
150
150
  identity: Identity | None = None,
151
- ) -> "User":
151
+ ) -> User:
152
152
  """Updates an existing user object in the repository
153
153
 
154
154
  Parameters
@@ -9,6 +9,8 @@ from alpha.domain.models.group import Group
9
9
 
10
10
  if TYPE_CHECKING:
11
11
  from alpha.domain.models.user import User
12
+ else:
13
+ User = Any
12
14
 
13
15
  DEFAULT_LDAP_MAPPINGS = {
14
16
  "subject": "uid",
@@ -158,7 +160,7 @@ class Identity:
158
160
  populate_groups: bool = True,
159
161
  populate_permissions: bool = False,
160
162
  populate_claims: bool = True,
161
- ) -> "Identity":
163
+ ) -> Identity:
162
164
  """Instantiate an Identity from an LDAP entry dictionary.
163
165
 
164
166
  Parameters
@@ -211,7 +213,7 @@ class Identity:
211
213
  )
212
214
 
213
215
  @classmethod
214
- def from_dict(cls, data: Mapping[str, Any]) -> "Identity":
216
+ def from_dict(cls, data: Mapping[str, Any]) -> Identity:
215
217
  """Instantiate an Identity from a generic dictionary.
216
218
 
217
219
  Parameters
@@ -252,7 +254,7 @@ class Identity:
252
254
  )
253
255
 
254
256
  @classmethod
255
- def from_user(cls, user: User) -> "Identity":
257
+ def from_user(cls, user: User) -> Identity:
256
258
  """Instantiate an Identity from a User instance.
257
259
 
258
260
  Parameters
@@ -1,5 +1,5 @@
1
1
  from alpha import exceptions
2
- from alpha.infra.connectors.sql_alchemy import SqlAlchemyDatabase
2
+ from alpha.interfaces.sql_database import SqlDatabase
3
3
  from alpha.providers.models.token import Token
4
4
 
5
5
 
@@ -15,7 +15,7 @@ class DatabaseRefreshRepository:
15
15
 
16
16
  def __init__(
17
17
  self,
18
- database_connector: SqlAlchemyDatabase,
18
+ database_connector: SqlDatabase,
19
19
  token_model: type[Token] = Token,
20
20
  token_max_age_seconds: int = 7 * 24 * 3600,
21
21
  token_length: int = 32,
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass
2
- from http import cookies
2
+ from http.cookies import SimpleCookie
3
3
  from typing import Mapping, Self
4
4
 
5
5
 
@@ -16,12 +16,28 @@ class Headers:
16
16
 
17
17
  This class is designed to be immutable and uses slots for memory
18
18
  efficiency.
19
+
20
+ Attributes
21
+ ----------
22
+ auth_token
23
+ The authentication token, typically a JWT, extracted from the
24
+ "Authorization" header or from cookies.
25
+ auth_token_type
26
+ The type of the authentication token, typically "Bearer".
27
+ refresh_token
28
+ The refresh token, extracted from the "X-Refresh-Token" header or from
29
+ cookies.
30
+ api_key
31
+ The API key, extracted from the "X-API-Key" header or from cookies.
32
+ cookies
33
+ A mapping of cookie names to their values, if any cookies are present.
19
34
  """
20
35
 
21
36
  auth_token: str | None = None
22
37
  auth_token_type: str | None = None
23
38
  refresh_token: str | None = None
24
39
  api_key: str | None = None
40
+ _cookie_jar: SimpleCookie | None = None
25
41
 
26
42
  @classmethod
27
43
  def from_headers(
@@ -73,8 +89,9 @@ class Headers:
73
89
  api_key = headers.get("X-API-Key")
74
90
  cookies_header = headers.get("Cookie")
75
91
 
92
+ cookie_jar: SimpleCookie | None = None
76
93
  if cookies_header is not None:
77
- cookie_jar = cookies.SimpleCookie(cookies_header)
94
+ cookie_jar = SimpleCookie(cookies_header)
78
95
 
79
96
  if not auth_token and auth_token_cookie_name in cookie_jar:
80
97
  auth_token = cookie_jar[auth_token_cookie_name].value
@@ -89,6 +106,7 @@ class Headers:
89
106
  auth_token_type=auth_token_type,
90
107
  refresh_token=refresh_token,
91
108
  api_key=api_key,
109
+ _cookie_jar=cookie_jar,
92
110
  )
93
111
 
94
112
  @property
@@ -107,6 +125,20 @@ class Headers:
107
125
  def has_api_key(self) -> bool:
108
126
  return True if self.api_key else False
109
127
 
128
+ @property
129
+ def cookies(self) -> dict[str, str]:
130
+ """Return a dictionary of cookies extracted from the request headers.
131
+
132
+ Returns
133
+ -------
134
+ dict[str, str]
135
+ A dictionary mapping cookie names to their values. If no cookies
136
+ are present, an empty dictionary is returned.
137
+ """
138
+ if self._cookie_jar is None:
139
+ return {}
140
+ return self._cookie_jar_to_dict(self._cookie_jar)
141
+
110
142
  def __repr__(self) -> str:
111
143
  return (
112
144
  f"Headers(auth_token={'***' if self.auth_token else None}, "
@@ -114,3 +146,19 @@ class Headers:
114
146
  f"refresh_token={'***' if self.refresh_token else None}, "
115
147
  f"api_key={'***' if self.api_key else None})"
116
148
  )
149
+
150
+ @staticmethod
151
+ def _cookie_jar_to_dict(cookie_jar: SimpleCookie) -> dict[str, str]:
152
+ """Convert a SimpleCookie object to a dictionary.
153
+
154
+ Parameters
155
+ ----------
156
+ cookie_jar
157
+ A SimpleCookie object containing the cookies.
158
+
159
+ Returns
160
+ -------
161
+ dict[str, str]
162
+ A dictionary mapping cookie names to their values.
163
+ """
164
+ return {key: morsel.value for key, morsel in cookie_jar.items()}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpha-python
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Alpha is intended to be the first dependency you need to add to your Python application. It is a Python library which contains standard building blocks that can be used in applications that are used as APIs and/or make use of database interaction.
5
5
  Author-email: Bart Reijling <bart@reijling.eu>
6
6
  License-Expression: MIT
@@ -34,7 +34,7 @@ Requires-Dist: argon2-cffi>=25.1.0
34
34
  Requires-Dist: httpx
35
35
  Requires-Dist: cryptography
36
36
  Provides-Extra: api-generator
37
- Requires-Dist: openapi-generator-cli==7.23.0; extra == "api-generator"
37
+ Requires-Dist: openapi-generator-cli==7.24.0; extra == "api-generator"
38
38
  Requires-Dist: jdk4py; extra == "api-generator"
39
39
  Provides-Extra: flask
40
40
  Requires-Dist: connexion[swagger-ui]<3,>=2.14.2; extra == "flask"
@@ -14,7 +14,7 @@ httpx
14
14
  cryptography
15
15
 
16
16
  [api-generator]
17
- openapi-generator-cli==7.23.0
17
+ openapi-generator-cli==7.24.0
18
18
  jdk4py
19
19
 
20
20
  [flask]
File without changes
File without changes
File without changes