alpha-python 0.6.1__py3-none-any.whl → 0.6.3__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.
alpha/__init__.py CHANGED
@@ -20,7 +20,7 @@ from alpha.infra.connectors.oidc_connector import (
20
20
  KeyCloakOIDCConnector,
21
21
  )
22
22
  from alpha.infra.connectors.sql_alchemy import SqlAlchemyDatabase
23
- from alpha.infra.models.filter_operators import And, Or
23
+ from alpha.infra.models.filter_operators import And, Or, FilterOperator
24
24
  from alpha.infra.models.json_patch import JsonPatch
25
25
  from alpha.infra.models.order_by import OrderBy, Order
26
26
  from alpha.infra.models.search_filter import SearchFilter, Operator
@@ -116,6 +116,7 @@ __all__ = [
116
116
  "SqlAlchemyDatabase",
117
117
  "And",
118
118
  "Or",
119
+ "FilterOperator",
119
120
  "JsonPatch",
120
121
  "OrderBy",
121
122
  "Order",
alpha/encoder.py CHANGED
@@ -4,6 +4,7 @@ complex types into JSON format.
4
4
 
5
5
  import json
6
6
  from dataclasses import asdict, is_dataclass
7
+ from attrs import asdict as attrs_asdict
7
8
  from datetime import date, datetime, time
8
9
  from enum import Enum
9
10
  from json import encoder
@@ -14,8 +15,9 @@ import numpy as np # type: ignore[import-untyped]
14
15
  import pandas as pd # type: ignore[import-untyped]
15
16
  import six # type: ignore[import-untyped]
16
17
 
17
-
18
18
  from alpha.interfaces.openapi_model import OpenAPIModel
19
+ from alpha.utils.is_attrs import is_attrs
20
+ from alpha.utils.is_pydantic import is_pydantic
19
21
 
20
22
 
21
23
  class JSONEncoder(encoder.JSONEncoder):
@@ -72,11 +74,15 @@ class JSONEncoder(encoder.JSONEncoder):
72
74
  return o.isoformat()
73
75
  if isinstance(o, time):
74
76
  return o.isoformat()
77
+ if isinstance(o, type):
78
+ cls = getattr(o, "__name__", None)
79
+ return cls if cls is not None else str(o)
75
80
  if is_dataclass(o):
76
- if isinstance(o, type):
77
- cls = getattr(o, "__class__")
78
- return cls.__name__
79
- return asdict(o)
81
+ return asdict(o) # type: ignore
82
+ if is_attrs(o):
83
+ return attrs_asdict(o)
84
+ if is_pydantic(o):
85
+ return o.model_dump()
80
86
 
81
87
  try:
82
88
  return json.JSONEncoder.default(self, o)
@@ -3,12 +3,14 @@
3
3
  import json
4
4
  from dataclasses import MISSING, is_dataclass
5
5
  from enum import Enum
6
- from typing import Any, Iterable, get_args, get_origin
6
+ from typing import Any, Sequence, get_args, get_origin
7
7
 
8
8
  from alpha import exceptions
9
9
  from alpha.encoder import JSONEncoder
10
+ from alpha.interfaces.attrs_instance import AttrsInstance
10
11
  from alpha.interfaces.dataclass_instance import DataclassInstance
11
12
  from alpha.interfaces.openapi_model import OpenAPIModel
13
+ from alpha.interfaces.pydantic_instance import PydanticInstance
12
14
  from alpha.utils.is_attrs import is_attrs
13
15
  from alpha.utils.is_pydantic import is_pydantic
14
16
 
@@ -18,8 +20,13 @@ class ResponseFactory:
18
20
 
19
21
  def process(
20
22
  self,
21
- response: DataclassInstance | Iterable[DataclassInstance],
22
- cls: OpenAPIModel | Iterable[OpenAPIModel],
23
+ response: DataclassInstance
24
+ | Sequence[DataclassInstance]
25
+ | AttrsInstance
26
+ | Sequence[AttrsInstance]
27
+ | PydanticInstance
28
+ | Sequence[PydanticInstance],
29
+ cls: OpenAPIModel | Sequence[OpenAPIModel],
23
30
  ) -> object:
24
31
  """Mapping a dataclass instance or a collection of instances to an
25
32
  OpenAPI model
@@ -54,7 +61,7 @@ class ResponseFactory:
54
61
 
55
62
  # When the source instance and target class are of an iterable type
56
63
  if cls_origin in [list, tuple, set]:
57
- if isinstance(response, Iterable):
64
+ if isinstance(response, Sequence):
58
65
  arg = get_args(cls)[0]
59
66
  return [
60
67
  self.process(response=obj, cls=arg) for obj in response
@@ -12,6 +12,7 @@ from typing import List
12
12
  from alpha.factories.request_factory import RequestFactory
13
13
  from alpha.factories.response_factory import ResponseFactory
14
14
  from alpha.encoder import JSONEncoder
15
+ from alpha.providers.models.identity import Identity
15
16
  from alpha.utils.logging_level_checker import logging_level_checker
16
17
  from alpha.utils.response_object import create_response_object
17
18
  from alpha.utils.request_headers import Headers
@@ -43,9 +44,7 @@ from {{packageName}} import models as api_models
43
44
 
44
45
  {{#operations}}
45
46
  {{#operation}}
46
- {{#authMethods}}{{#vendorExtensions.x-alpha-service-name}}@inject{{/vendorExtensions.x-alpha-service-name}}{{/authMethods}}
47
- {{^authMethods}}{{#vendorExtensions.x-alpha-service-name}}@inject{{/vendorExtensions.x-alpha-service-name}}{{/authMethods}}
48
- {{#authMethods}}{{^vendorExtensions.x-alpha-service-name}}@inject{{/vendorExtensions.x-alpha-service-name}}{{/authMethods}}
47
+ {{#authMethods}}{{#-first}}@inject{{/-first}}{{/authMethods}}{{^authMethods}}{{#vendorExtensions.x-alpha-service-name}}@inject{{/vendorExtensions.x-alpha-service-name}}{{/authMethods}}
49
48
  def {{operationId}}(
50
49
  {{#allParams}}{{^isBodyParam}}{{paramName}}{{^required}}=None{{/required}},{{/isBodyParam}}{{/allParams}}
51
50
  {{#authMethods}}{{#isBasicBearer}}token_factory=Provide[Container.token_factory],{{/isBasicBearer}}{{/authMethods}}
@@ -229,7 +228,8 @@ def {{operationId}}(
229
228
  token_factory.validate(auth_token)
230
229
 
231
230
  # Get auth token payload and verify identity
232
- identity = token_factory.get_payload(auth_token)
231
+ payload = token_factory.get_payload(auth_token)
232
+ identity = Identity.from_dict(payload)
233
233
  verify_identity(identity,
234
234
  roles=roles,
235
235
  groups=groups,
@@ -309,8 +309,9 @@ def {{operationId}}(
309
309
  status_code={{code}},
310
310
  status_message='{{message}}',
311
311
  data=result,
312
- {{#vendorExtensions.x-content-type}}data_type='{{vendorExtensions.x-content-type}}'{{/vendorExtensions.x-content-type}}
313
- {{#vendorExtensions.x-alpha-cookie-support}}response_type='flask'{{/vendorExtensions.x-alpha-cookie-support}}
312
+ accept_header={{#vendorExtensions.x-content-type}}'{{vendorExtensions.x-content-type}}'{{/vendorExtensions.x-content-type}}{{^vendorExtensions.x-content-type}}connexion.request.headers.get("Accept", None){{/vendorExtensions.x-content-type}},
313
+ supported_accept_headers=[{{#produces}}'{{mediaType}}',{{/produces}}{{^produces}}{{#vendorExtensions.x-preferred-produce}}'{{mediaType}}',{{/vendorExtensions.x-preferred-produce}}{{/produces}}],
314
+ {{#vendorExtensions.x-alpha-cookie-support}}response_format='flask'{{/vendorExtensions.x-alpha-cookie-support}}
314
315
  )
315
316
  {{/returnType}}
316
317
  {{^returnType}}
@@ -318,19 +319,20 @@ def {{operationId}}(
318
319
  http_codes=http_codes,
319
320
  status_code=204,
320
321
  status_message='{{message}}',
321
- {{#vendorExtensions.x-alpha-cookie-support}}data=result, response_type='flask'{{/vendorExtensions.x-alpha-cookie-support}}
322
+ {{#vendorExtensions.x-alpha-cookie-support}}data=result, response_format='flask'{{/vendorExtensions.x-alpha-cookie-support}}
322
323
  )
323
324
  {{/returnType}}
324
325
  {{/vendorExtensions.x-alpha-raw-response}}
325
326
  {{/is2xx}}
326
-
327
327
  {{#is4xx}}
328
328
  {{#vendorExtensions.x-alpha-exception}}
329
329
  except {{vendorExtensions.x-alpha-exception}} as exc:
330
330
  return response_object_function(
331
331
  http_codes=http_codes,
332
332
  status_code={{code}},
333
- status_message=f'{exc}'
333
+ status_message=f'{exc}',
334
+ accept_header={{#vendorExtensions.x-content-type}}'{{vendorExtensions.x-content-type}}'{{/vendorExtensions.x-content-type}}{{^vendorExtensions.x-content-type}}connexion.request.headers.get("Accept", None){{/vendorExtensions.x-content-type}},
335
+ supported_accept_headers=[{{#produces}}'{{mediaType}}',{{/produces}}{{^produces}}{{#vendorExtensions.x-preferred-produce}}'{{mediaType}}',{{/vendorExtensions.x-preferred-produce}}{{/produces}}],
334
336
  )
335
337
  {{/vendorExtensions.x-alpha-exception}}
336
338
  {{/is4xx}}
@@ -341,6 +343,8 @@ def {{operationId}}(
341
343
  http_codes=http_codes,
342
344
  status_code={{code}},
343
345
  status_message=f'{exc}'
346
+ accept_header={{#vendorExtensions.x-content-type}}'{{vendorExtensions.x-content-type}}'{{/vendorExtensions.x-content-type}}{{^vendorExtensions.x-content-type}}connexion.request.headers.get("Accept", None){{/vendorExtensions.x-content-type}},
347
+ supported_accept_headers=[{{#produces}}'{{mediaType}}',{{/produces}}{{^produces}}{{#vendorExtensions.x-preferred-produce}}'{{mediaType}}',{{/vendorExtensions.x-preferred-produce}}{{/produces}}],
344
348
  )
345
349
  {{/vendorExtensions.x-alpha-exception}}
346
350
  {{/is5xx}}
alpha/infra/__init__.py CHANGED
@@ -3,7 +3,7 @@ from alpha.infra.connectors.oidc_connector import (
3
3
  KeyCloakOIDCConnector,
4
4
  )
5
5
  from alpha.infra.connectors.sql_alchemy import SqlAlchemyDatabase
6
- from alpha.infra.models.filter_operators import And, Or
6
+ from alpha.infra.models.filter_operators import And, Or, FilterOperator
7
7
  from alpha.infra.models.json_patch import JsonPatch
8
8
  from alpha.infra.models.order_by import OrderBy, Order
9
9
  from alpha.infra.models.search_filter import SearchFilter, Operator
@@ -22,6 +22,7 @@ __all__ = [
22
22
  "SqlAlchemyDatabase",
23
23
  "And",
24
24
  "Or",
25
+ "FilterOperator",
25
26
  "JsonPatch",
26
27
  "OrderBy",
27
28
  "Order",
@@ -31,6 +31,9 @@ class LDAPConnector:
31
31
  server_port: int = 636,
32
32
  use_tls: bool = True,
33
33
  client_strategy: ClientStrategyType = SYNC,
34
+ connect_timeout: float | None = 5.0,
35
+ additional_connector_params: dict[str, Any] | None = None,
36
+ additional_server_params: dict[str, Any] | None = None,
34
37
  ) -> None:
35
38
  """
36
39
  Parameters
@@ -59,12 +62,29 @@ class LDAPConnector:
59
62
  - 'MOCK_SYNC': Mock synchronous strategy.
60
63
  - 'MOCK_ASYNC': Mock asynchronous strategy.
61
64
  - 'ASYNC_STREAM': Asynchronous stream strategy.
65
+ connect_timeout
66
+ Maximum number of seconds to wait while opening the socket.
67
+ additional_connector_params
68
+ Additional parameters to pass to the LDAP connection, by default
69
+ {"receive_timeout": 5}
70
+ additional_server_params
71
+ Additional parameters to pass to the LDAP server, by default None
62
72
  """
63
73
  self._server_url = server_url
64
74
  self._bind_dn = bind_dn
65
75
  self._bind_password = bind_password
66
76
  self._client_strategy = client_strategy
67
-
77
+ self._connect_timeout = connect_timeout
78
+ self._additional_connector_params: dict[str, Any] = (
79
+ {"receive_timeout": 5}
80
+ if additional_connector_params is None
81
+ else dict(additional_connector_params)
82
+ )
83
+ self._additional_server_params: dict[str, Any] = (
84
+ {}
85
+ if additional_server_params is None
86
+ else dict(additional_server_params)
87
+ )
68
88
  tls = None
69
89
  if use_tls:
70
90
  tls = Tls(
@@ -78,6 +98,8 @@ class LDAPConnector:
78
98
  use_ssl=use_tls,
79
99
  tls=tls,
80
100
  get_info=ALL,
101
+ connect_timeout=self._connect_timeout,
102
+ **self._additional_server_params,
81
103
  )
82
104
  self._connection: Connection | None = None
83
105
 
@@ -97,8 +119,9 @@ class LDAPConnector:
97
119
  self._server,
98
120
  user=self._bind_dn,
99
121
  password=self._bind_password,
100
- auto_bind=True,
101
122
  client_strategy=self._client_strategy, # type: ignore
123
+ auto_bind=True,
124
+ **self._additional_connector_params,
102
125
  )
103
126
 
104
127
  def disconnect(self) -> None:
@@ -4,7 +4,7 @@
4
4
  - Or
5
5
  """
6
6
 
7
- from typing import Any, Callable, Iterable
7
+ from typing import Any, Callable, Iterable, Self
8
8
 
9
9
  from sqlalchemy.orm import Query
10
10
  from sqlalchemy.sql.expression import ColumnElement, and_, or_
@@ -17,13 +17,11 @@ class FilterOperator:
17
17
  search query
18
18
  """
19
19
 
20
- def __init__(self, *search_filters: SearchFilter):
20
+ def __init__(self, *search_filters: SearchFilter | Self) -> None:
21
21
  """Instantiate the filter operator by storing the search filter
22
22
  objects
23
23
  """
24
- self.search_filters: Iterable[SearchFilter | FilterOperator] = (
25
- search_filters
26
- )
24
+ self.search_filters: Iterable[SearchFilter | Self] = search_filters
27
25
 
28
26
  @property
29
27
  def filter_operator(
@@ -32,5 +32,3 @@ class SqlDatabase(Protocol):
32
32
  def drop_tables(
33
33
  self, metadata: sa.MetaData, tables: list[sa.Table] | None = None
34
34
  ) -> None: ...
35
-
36
- def _create_schema(self, engine: Engine, schema_name: str) -> None: ...
@@ -1,8 +1,8 @@
1
- from typing import TYPE_CHECKING, Any, Literal, overload
2
1
  import json
3
- from alpha.encoder import JSONEncoder
4
- from alpha.utils.cookie import Cookie
2
+ from typing import TYPE_CHECKING, Any, Literal, overload
3
+
5
4
  from alpha.utils._http_codes import http_codes_en
5
+ from alpha.utils.cookie import Cookie
6
6
 
7
7
  if TYPE_CHECKING:
8
8
  from flask.wrappers import Response
@@ -15,10 +15,12 @@ def create_response_object(
15
15
  status_code: int,
16
16
  status_message: str,
17
17
  data: Any | None,
18
- data_type: str,
18
+ accept_header: str,
19
+ supported_accept_headers: list[str] | None,
19
20
  http_codes: dict[int, tuple[str, str]],
20
21
  json_encoder: type[json.JSONEncoder] | None,
21
- response_type: Literal["dict"],
22
+ response_format: Literal["dict"],
23
+ **kwargs: Any,
22
24
  ) -> tuple[dict[str, Any], int]: ...
23
25
 
24
26
 
@@ -27,10 +29,12 @@ def create_response_object(
27
29
  status_code: int,
28
30
  status_message: str,
29
31
  data: Any | None,
30
- data_type: str,
32
+ accept_header: str,
33
+ supported_accept_headers: list[str] | None,
31
34
  http_codes: dict[int, tuple[str, str]],
32
35
  json_encoder: type[json.JSONEncoder] | None,
33
- response_type: Literal["flask"],
36
+ response_format: Literal["flask"],
37
+ **kwargs: Any,
34
38
  ) -> tuple[Response, int]: ...
35
39
 
36
40
 
@@ -39,10 +43,12 @@ def create_response_object(
39
43
  status_code: int,
40
44
  status_message: str,
41
45
  data: Any | None,
42
- data_type: str,
46
+ accept_header: str,
47
+ supported_accept_headers: list[str] | None,
43
48
  http_codes: dict[int, tuple[str, str]],
44
49
  json_encoder: type[json.JSONEncoder] | None,
45
- response_type: None = None,
50
+ response_format: None = None,
51
+ **kwargs: Any,
46
52
  ) -> tuple[dict[str, Any], int]: ...
47
53
 
48
54
 
@@ -50,16 +56,20 @@ def create_response_object(
50
56
  status_code: int,
51
57
  status_message: str,
52
58
  data: Any | None = None,
53
- data_type: str = "application/json",
59
+ accept_header: str = "application/json",
60
+ supported_accept_headers: list[str] | None = None,
54
61
  http_codes: dict[int, tuple[str, str]] = http_codes_en,
55
- json_encoder: type[json.JSONEncoder] | None = JSONEncoder,
56
- response_type: str | None = "dict",
62
+ json_encoder: type[json.JSONEncoder] | None = None,
63
+ response_format: str | None = "dict",
64
+ **kwargs: Any,
57
65
  ) -> tuple[Response, int] | tuple[dict[str, Any], int]:
58
66
  """Create a HTTP response object.
59
67
 
60
68
  The response object can be either a dictionary or a Flask Response object,
61
- depending on the value of `response_type`. The response will include the
69
+ depending on the value of `response_format`. The response will include the
62
70
  status code, a human-readable message, and optionally additional data.
71
+ Only supports JSON responses. For other types, use custom function with
72
+ x-alpha-custom-response-builder in the OpenAPI specification.
63
73
 
64
74
  Parameters
65
75
  ----------
@@ -69,15 +79,18 @@ def create_response_object(
69
79
  Human-readable message describing the status.
70
80
  data
71
81
  Additional data to include in the response, by default None
72
- data_type
73
- The MIME type of the response, by default "application/json"
82
+ accept_header
83
+ The value of the Accept header from the request,
84
+ by default "application/json"
85
+ supported_accept_headers
86
+ A list of supported MIME types for the data_type parameter.
74
87
  http_codes
75
88
  A dictionary mapping HTTP status codes to their descriptions, by
76
89
  default http_codes_en
77
90
  json_encoder
78
91
  A custom JSON encoder class to use when encoding the response data, by
79
- default alpha.encoder.JSONEncoder
80
- response_type
92
+ default None. If None, the default JSONEncoder will be used.
93
+ response_format
81
94
  The type of response to create, either "flask" or "dict", by default
82
95
  "dict"
83
96
 
@@ -85,13 +98,21 @@ def create_response_object(
85
98
  -------
86
99
  tuple[dict[str, Any], int]
87
100
  A tuple containing the response object as a dictionary and the HTTP
88
- status code. When response_type is "dict".
101
+ status code. When response_format is "dict".
89
102
  tuple[Response, int]
90
103
  A tuple containing the flask.Response object and the HTTP status code.
91
- When response_type is "flask".
104
+ When response_format is "flask".
92
105
  """
93
- if response_type is None:
94
- response_type = "dict"
106
+ data_type = _resolve_data_type(accept_header, supported_accept_headers)
107
+
108
+ if response_format is None:
109
+ response_format = "dict"
110
+
111
+ if json_encoder is None:
112
+ # Lazily import to avoid circular import during alpha package init.
113
+ from alpha.encoder import JSONEncoder
114
+
115
+ json_encoder = JSONEncoder
95
116
 
96
117
  obj: dict[str, Any] = {
97
118
  "detail": status_message,
@@ -100,7 +121,7 @@ def create_response_object(
100
121
  "type": data_type or "about:blank",
101
122
  }
102
123
 
103
- if response_type == "flask":
124
+ if response_format == "flask":
104
125
  # Importing Flask's Response class here lazily to avoid unnecessary
105
126
  # dependencies when not using Flask.
106
127
  from flask.wrappers import Response
@@ -138,7 +159,7 @@ def create_response_object(
138
159
 
139
160
  return resp, status_code
140
161
 
141
- if response_type == "dict":
162
+ if response_format == "dict":
142
163
  if data is not None:
143
164
  obj["data"] = data
144
165
  return obj, status_code
@@ -158,6 +179,7 @@ def _split_cookies_from_object(
158
179
 
159
180
  Returns
160
181
  -------
182
+ tuple[Any | None, list[Cookie]]
161
183
  A tuple containing the data and a list of Cookie objects representing
162
184
  the cookies.
163
185
  """
@@ -175,3 +197,48 @@ def _split_cookies_from_object(
175
197
  data = data[0]
176
198
  return data, cookies
177
199
  return obj, []
200
+
201
+
202
+ def _resolve_data_type(
203
+ accept_header: str | None,
204
+ supported_accept_headers: list[str] | None,
205
+ default: str = "application/json",
206
+ ) -> str:
207
+ """Resolve the data type for the response by matching against the supported
208
+ types.
209
+
210
+ Match wildcards like "*/*" or "application/*" with first match in supported
211
+ types. If the data type is not supported, resort to default type.
212
+
213
+ Parameters
214
+ ----------
215
+ accept_header
216
+ The Accept header from the request.
217
+ supported_accept_headers
218
+ A list of supported MIME types. If None, all types are supported.
219
+ default
220
+ The default MIME type to use if the provided accept_header is not
221
+ supported.
222
+
223
+ Returns
224
+ -------
225
+ str
226
+ The resolved MIME type to use for the response.
227
+ """
228
+ # If no data type provided or no supported types, return default
229
+ if not accept_header or not supported_accept_headers:
230
+ return default
231
+ # Return provided type if it matches supported type
232
+ if accept_header.lower() in supported_accept_headers:
233
+ return accept_header.lower()
234
+ # If MIME type wildcard is provided, return first supported type
235
+ if accept_header.startswith("*/"):
236
+ return supported_accept_headers[0]
237
+ # If MIME subtype is a wildcard, match prefix
238
+ if accept_header.endswith("/*"):
239
+ prefix = accept_header.split("/")[0].lower()
240
+ for supported in supported_accept_headers:
241
+ if supported.startswith(prefix):
242
+ return supported
243
+ # If not matched, return default
244
+ return default
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alpha-python
3
- Version: 0.6.1
3
+ Version: 0.6.3
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
@@ -1,6 +1,6 @@
1
- alpha/__init__.py,sha256=tktKTmPjYOf91PvLdmlczAyjguUt9UnSdN8qGBU4npw,6115
1
+ alpha/__init__.py,sha256=FnXcEv9PSCLWDKE4-9GCqI7HSAvzo3WW_mfcBLPBBxo,6153
2
2
  alpha/cli.py,sha256=YTWM7lzmydYazXMJ6LULywvJTMHzvfTO6yNuPrUgHCY,5813
3
- alpha/encoder.py,sha256=sNYZ30uNiJWV0xpeIiTVCDAsM86Nk_914kF7Ye2Woao,2610
3
+ alpha/encoder.py,sha256=dPFDfCofX2ehhOZuC7EEoj00l5sclE-BAvq01oQpo4o,2891
4
4
  alpha/exceptions.py,sha256=AHoFMPyHvjj6j_1X2TS40dSaFBzCDtgzAmucimSZjfc,5793
5
5
  alpha/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  alpha/adapters/__init__.py,sha256=pGpAtLuVs-jOyRShjO1BwSHpB5MyStJ3Hs9wPm49Q2s,201
@@ -26,7 +26,7 @@ alpha/factories/logging_handler_factory.py,sha256=ZoVkD2S3Pl7NMMfhcFF8k76BlKTsvi
26
26
  alpha/factories/model_class_factory.py,sha256=VK80vLHGF-XdlW3aln5C9tHSQv81NLxz5ti5jYxdv4w,5862
27
27
  alpha/factories/password_factory.py,sha256=uK8X5bNvlyUtxvJXH7MXmYLiaM4jmsS6sZrx7Ew07kM,5031
28
28
  alpha/factories/request_factory.py,sha256=vjkvsBkKKUZ7me5a8cEcFYet03qnUZ6f5Qyktfxospw,7159
29
- alpha/factories/response_factory.py,sha256=mmHRWa7TRjZMuIPojI69At1Q21bBa-qiH9LLtKngGM8,6497
29
+ alpha/factories/response_factory.py,sha256=du2tqJdqzTSIpWeC3z8LmVKKZHqrLZ-1G42TBLbIQG4,6749
30
30
  alpha/factories/type_factories.py,sha256=3MCSQ1g1neBVPk0cSbhmGED7O4AQNMmBK8OmTLwuaGM,6478
31
31
  alpha/factories/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  alpha/factories/models/factory_classes.py,sha256=RpmJdPmC5MUNTD4TK6TaqBzd2ezLGSjsHGltl-_6tqo,1131
@@ -48,7 +48,7 @@ alpha/handlers/templates/python-flask/__init__model.mustache,sha256=JRwyJmOCAD8n
48
48
  alpha/handlers/templates/python-flask/__init__test.mustache,sha256=wUxDXcyE4rPh3sDp8MvR5m8vqzoU25Fw1bo_xh6InnY,438
49
49
  alpha/handlers/templates/python-flask/__main__.mustache,sha256=D11Z_bhka_NsK3EP8iSzV8_Hcc15L-uOntH2IbzrKng,2942
50
50
  alpha/handlers/templates/python-flask/base_model.mustache,sha256=B--jl9LmfiHACq9n1kDxm6YTi6tb1oSUFnZya_IKOhU,2184
51
- alpha/handlers/templates/python-flask/controller.mustache,sha256=ittIpaeSeXfpmSEYm2HhLejjh4YcAmvOmSzWzdtnRUQ,17528
51
+ alpha/handlers/templates/python-flask/controller.mustache,sha256=wDY6EcZ6UiCkBXQKVrzhbOn_zAY6szW3jYNI0LiMohs,18691
52
52
  alpha/handlers/templates/python-flask/controller_test.mustache,sha256=2i2cwgQonT1RMJQwdxeq8B3x8-hLjpK7YkI--LkKLOI,2848
53
53
  alpha/handlers/templates/python-flask/dockerignore.mustache,sha256=hqlHuqIMLuuwvVqK6xhIcfaezKoChriR3D7TvxtkjGo,906
54
54
  alpha/handlers/templates/python-flask/encoder.mustache,sha256=03rsvhN_QdqaWsQC2v3772UvrLEXna9WcvxQsl6mwiU,866
@@ -65,15 +65,15 @@ alpha/handlers/templates/python-flask/tox.mustache,sha256=iuEc1JquvGZ0UlCCJus2X_
65
65
  alpha/handlers/templates/python-flask/travis.mustache,sha256=M9UNXQnfg8F6uFvOSsay8FQ0YvPDi8EF6HIiu4UW4-o,319
66
66
  alpha/handlers/templates/python-flask/typing_utils.mustache,sha256=mGDTJkj9V9w7NsFSljw33GKB-gWfqoceAot-iHTViNs,809
67
67
  alpha/handlers/templates/python-flask/util.mustache,sha256=iQVhsAN_ZCQuQGOxoqATTE90fkIEojKyrfooFqa7Jck,3534
68
- alpha/infra/__init__.py,sha256=M52HIbeT0yvgwtU2yEPpOpF12p2dxXfCBfm_Fj796mU,980
68
+ alpha/infra/__init__.py,sha256=4eIKsW1N06_vVBrO2u1ESU5iURBb0cGvxcscaPsB4PE,1018
69
69
  alpha/infra/connectors/__init__.py,sha256=kEh_mOIIqkWeY4cilislM8ZjKXNFp8zBuMThfbJ1CGc,647
70
- alpha/infra/connectors/ldap_connector.py,sha256=ntBheImY90qtZ8tTYv0Dh64vxNho0k8FwTOAYkVdZsU,4019
70
+ alpha/infra/connectors/ldap_connector.py,sha256=Ce2IspqcrTEkYwlhxoh8QOzEK51-ZcJ9t6RCytk0Ob8,5132
71
71
  alpha/infra/connectors/oidc_connector.py,sha256=z9AY1lMVK5nULd80zOvJzo8zPbp6CHJ7fv2smp71eIs,15675
72
72
  alpha/infra/connectors/sql_alchemy.py,sha256=8DivUj25_OAVaXmaCsbSnHgOD1w5_ewAXSlZ-cxuMVk,5116
73
73
  alpha/infra/databases/__init__.py,sha256=IyA_aB9h_7rOM-aa50QLsA_q4e9W4HnJOqh76aDyrj4,106
74
74
  alpha/infra/databases/sql_alchemy.py,sha256=7t17M8UEgW1NMX9LYW6A14EM5UxEJZyp-8a_xLEONAs,235
75
75
  alpha/infra/models/__init__.py,sha256=SIakw9bAPXwFmx3I7exCRBs3e2Ug3etOJy6JyIOR1Uc,348
76
- alpha/infra/models/filter_operators.py,sha256=SbI5jlFYOdoNPfIYYKvvhesAENipWj2Zlh31g4e6EKQ,2812
76
+ alpha/infra/models/filter_operators.py,sha256=LJw2w8v1FvDhQnEZ8hKq3Rq54_MwolGn7SSDT5t5rT4,2797
77
77
  alpha/infra/models/json_patch.py,sha256=w8L59E6w-aSeEknww-JLCrB1kEpFbPXcRlweKP4kU1A,1753
78
78
  alpha/infra/models/order_by.py,sha256=QN4ALsbJ-zoh1dx5OHZ2L9pijwfjBM5G0pBbpNrNHnM,4569
79
79
  alpha/infra/models/query_clause.py,sha256=xLWxm-cWrODMqpqqVIu1veSVBWLENt97TTHq8CinP7M,2555
@@ -88,7 +88,7 @@ alpha/interfaces/openapi_model.py,sha256=9QayfwbwTg_3-reFso_ktwNqGI2f2C4AQOAPvPH
88
88
  alpha/interfaces/patchable.py,sha256=9L42VdrvfDhKKlfjQAMDX6FDA0R-U6QkOWlAHUdxneQ,705
89
89
  alpha/interfaces/providers.py,sha256=S0uBThEI_qqRpxyQmwNNSPGMcAVIU2ngXIimflDqUbc,4162
90
90
  alpha/interfaces/pydantic_instance.py,sha256=S96jLEWRmDyvYV3VqofSqjiN-lcjfkjiNp7Vpumw49A,245
91
- alpha/interfaces/sql_database.py,sha256=H52NR1ti2j9G9zJsibPtKmXL7WdHOzeSyPXO4Zq9wlA,996
91
+ alpha/interfaces/sql_database.py,sha256=-YiMBSrGkd2NTS4FEBjXenlPnVQW2t3SvQJMDRyHDjA,919
92
92
  alpha/interfaces/sql_mapper.py,sha256=OSGIwbtlQ5-cBHUIiJfLgJlkBU3MgMAbSdxj8X2v-eI,624
93
93
  alpha/interfaces/sql_repository.py,sha256=nJCdF_G8YS7_VST_OL14wBA_Ne_DyGZhQQDAta1zqYk,9814
94
94
  alpha/interfaces/token_factory.py,sha256=MeSvnyH699vBG0c7Oli4M6RT1wEsCVTNy7V4XQpu31o,1882
@@ -125,7 +125,7 @@ alpha/utils/is_pydantic.py,sha256=-P4n3n59_YftVqvIIQ_GovxUxQMFIt8htTDd0j2hFis,62
125
125
  alpha/utils/logging_configurator.py,sha256=wnwcBjI4wzvz2R0oMgEHffoGo9FfgPhf-1ZIlA9Eydo,3817
126
126
  alpha/utils/logging_level_checker.py,sha256=elCxkVW07BnVGPhIHf_TQyHCAPpdNY8xp5bszrziRS0,697
127
127
  alpha/utils/request_headers.py,sha256=z_0mDT4NoQimG1zPCyM5-7T64BJ91eQXNILuIc08cYI,4310
128
- alpha/utils/response_object.py,sha256=AymBt3qrirpLRkS0DcVkoxVLKZ3R0Eb6A5cN4cgFs9E,5372
128
+ alpha/utils/response_object.py,sha256=UsmL50ziE2rRjGLdzGEdQ99YWTUbIUWjBN7OGO4cneg,7811
129
129
  alpha/utils/secret_generator.py,sha256=LjsKb8oDfsfmCCcTKrqtw_duqJ7u3V_o6zGGuG26_XE,393
130
130
  alpha/utils/verify_identity.py,sha256=Y1pdcVl8Z_I4ibw2KY7i5QwTQrY29WwpBOJ6j0YOAow,2271
131
131
  alpha/utils/version_checker.py,sha256=W8v69hDbrr0VvJ40gpFmXMtVawrDmUz_YGWssKUTmVE,380
@@ -136,9 +136,9 @@ alpha/utils/openapi_test/models.py,sha256=vAHbjmwc0rVsCj9m8iKqkwPpSkSmkTOT8UQvff
136
136
  alpha/utils/openapi_test/orm.py,sha256=Py95GV_0e7wI1MYDZR1_EHkvTgev6eNo70SVmnD7kGc,3045
137
137
  alpha/utils/openapi_test/response.py,sha256=IxbQ6Nw258LLViHkgfjOpc7zWGTP8ofVOX1zrwDoR50,270
138
138
  alpha/utils/openapi_test/service.py,sha256=ycrEUlQmygKthnOhEiir-wtbPFi5cT-bepVclaL9FAk,5003
139
- alpha_python-0.6.1.dist-info/licenses/LICENSE,sha256=5KwEqC3KUoH4lVXgZ9tGriKOl-LGxHkXBWo16mFmAYM,1070
140
- alpha_python-0.6.1.dist-info/METADATA,sha256=TBRRf51v3Gldx6fFVhi8Tqva-txOBAJpUbizSmiiBCk,8645
141
- alpha_python-0.6.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
142
- alpha_python-0.6.1.dist-info/entry_points.txt,sha256=LBEXdcofOugYYdZ46nz5Dxj_aj1QbRBkumfPGhy-GXI,41
143
- alpha_python-0.6.1.dist-info/top_level.txt,sha256=tqmNnOmi2RSSiPo99C03fD5Cc3r9za9xTjPAoQC1EGA,6
144
- alpha_python-0.6.1.dist-info/RECORD,,
139
+ alpha_python-0.6.3.dist-info/licenses/LICENSE,sha256=5KwEqC3KUoH4lVXgZ9tGriKOl-LGxHkXBWo16mFmAYM,1070
140
+ alpha_python-0.6.3.dist-info/METADATA,sha256=aXEewzfWErO4dI6yI4a_in5JbWrtMPbEM2sZuicqwS8,8645
141
+ alpha_python-0.6.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
142
+ alpha_python-0.6.3.dist-info/entry_points.txt,sha256=LBEXdcofOugYYdZ46nz5Dxj_aj1QbRBkumfPGhy-GXI,41
143
+ alpha_python-0.6.3.dist-info/top_level.txt,sha256=tqmNnOmi2RSSiPo99C03fD5Cc3r9za9xTjPAoQC1EGA,6
144
+ alpha_python-0.6.3.dist-info/RECORD,,