fastlifeweb 0.25.1__py3-none-any.whl → 0.26.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.
CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.26.0 - Released on 2025-03-08
2
+ * Add a new method to the configuration to customize the request class.
3
+ See [Configurator.set_request_factory](#fastlife.config.configurator.GenericConfigurator.set_request_factory)
4
+
5
+ ## 0.25.2 - Released on 2025-03-03
6
+ * Update deps and fix related bugs in JinjaX components.
7
+
1
8
  ## 0.25.1 - Released on 2025-03-02
2
9
  * Update fews JinjaX components
3
10
  * New attributes on Input
fastlife/__init__.py CHANGED
@@ -23,6 +23,7 @@ from .config import (
23
23
  resource_view,
24
24
  view_config,
25
25
  )
26
+ from .domain.model.asgi import ASGIRequest, ASGIResponse
26
27
  from .domain.model.form import FormModel
27
28
  from .domain.model.request import GenericRequest
28
29
  from .domain.model.security_policy import (
@@ -36,6 +37,8 @@ from .domain.model.security_policy import (
36
37
  NoMFAAuthenticationState,
37
38
  PendingMFA,
38
39
  PreAuthenticated,
40
+ TClaimedIdentity,
41
+ TIdentity,
39
42
  Unauthenticated,
40
43
  Unauthorized,
41
44
  )
@@ -43,6 +46,7 @@ from .domain.model.template import JinjaXTemplate
43
46
 
44
47
  # from .request.form_data import model
45
48
  from .service.registry import DefaultRegistry, GenericRegistry, TRegistry, TSettings
49
+ from .service.request_factory import RequestFactory
46
50
  from .service.security_policy import (
47
51
  AbstractNoMFASecurityPolicy,
48
52
  AbstractSecurityPolicy,
@@ -75,6 +79,10 @@ __all__ = [
75
79
  "AnyRequest",
76
80
  "Request",
77
81
  "get_request",
82
+ # Request Factory
83
+ "ASGIRequest",
84
+ "ASGIResponse",
85
+ "RequestFactory",
78
86
  # Response
79
87
  "Response",
80
88
  "RedirectResponse",
@@ -94,6 +102,8 @@ __all__ = [
94
102
  "Authenticated",
95
103
  "AuthenticationState",
96
104
  "NoMFAAuthenticationState",
105
+ "TClaimedIdentity",
106
+ "TIdentity",
97
107
  # Template
98
108
  "JinjaXTemplate",
99
109
  # i18n
@@ -4,10 +4,8 @@ from collections.abc import Callable, Coroutine
4
4
  from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from fastapi.routing import APIRoute
7
- from starlette.requests import Request as StarletteRequest
8
- from starlette.responses import Response
9
7
 
10
- from fastlife.domain.model.request import GenericRequest
8
+ from fastlife.domain.model.asgi import ASGIRequest, ASGIResponse
11
9
 
12
10
  if TYPE_CHECKING:
13
11
  from fastlife.service.registry import DefaultRegistry # coverage: ignore
@@ -34,14 +32,14 @@ class Route(APIRoute):
34
32
 
35
33
  def get_route_handler(
36
34
  self,
37
- ) -> Callable[[StarletteRequest], Coroutine[Any, Any, Response]]:
35
+ ) -> Callable[[ASGIRequest], Coroutine[Any, Any, ASGIResponse]]:
38
36
  """
39
37
  Replace the request object by the fastlife request associated with the registry.
40
38
  """
41
39
  orig_route_handler = super().get_route_handler()
42
40
 
43
- async def route_handler(request: StarletteRequest) -> Response:
44
- req = GenericRequest[Any, Any, Any](self._registry, request)
41
+ async def route_handler(request: ASGIRequest) -> ASGIResponse:
42
+ req = self._registry.request_factory(request)
45
43
  return await orig_route_handler(req)
46
44
 
47
45
  return route_handler
@@ -60,7 +60,7 @@ class SequenceWidget(Widget[Sequence[TWidget]]):
60
60
 
61
61
  item_type: type[Any]
62
62
  wrapped_type: TypeWrapper | None = Field(default=None)
63
- children_widgets: list[str] = Field(default=None)
63
+ children_widgets: list[str] | None = Field(default=None)
64
64
 
65
65
  def build_item_type(self, route_prefix: str) -> TypeWrapper:
66
66
  return TypeWrapper(self.item_type, route_prefix, self.name, self.token)
@@ -55,7 +55,7 @@ class PasswordWidget(Widget[SecretStr]):
55
55
  new_password: bool = Field(default=False)
56
56
 
57
57
 
58
- class TextareaWidget(Widget[Sequence[str]]):
58
+ class TextareaWidget(Widget[str | Sequence[str]]):
59
59
  """
60
60
  Render a Textearea for a string or event a sequence of string.
61
61
 
@@ -84,11 +84,10 @@ class TextareaWidget(Widget[Sequence[str]]):
84
84
  <Label :for="id">{{title}}</Label>
85
85
  <pydantic_form.Error :text="error" />
86
86
  <Textarea :name="name" :id="id" :aria-label="aria_label">
87
- {%- if v is string -%}
88
- {{- v -}}}
87
+ {%- if value is string -%}
88
+ {{- value -}}
89
89
  {%- else -%}
90
- {%- for v in value %}{{v}}
91
- {% endfor -%}
90
+ {%- for v in value %}{{v}}{{"\n"}}{% endfor -%}
92
91
  {% endif %}
93
92
  </Textarea>
94
93
  <pydantic_form.Hint :text="hint" />
@@ -44,13 +44,15 @@ from fastlife.shared_utils.resolver import (
44
44
  )
45
45
 
46
46
  if TYPE_CHECKING:
47
+ from fastlife.service.locale_negociator import LocaleNegociator # coverage: ignore
48
+ from fastlife.service.request_factory import (
49
+ RequestFactoryBuilder, # coverage: ignore
50
+ )
47
51
  from fastlife.service.security_policy import AbstractSecurityPolicy
48
52
  from fastlife.service.templates import (
49
53
  AbstractTemplateRendererFactory, # coverage: ignore
50
54
  )
51
55
 
52
- from fastlife.service.locale_negociator import LocaleNegociator
53
-
54
56
  log = logging.getLogger(__name__)
55
57
  VENUSIAN_CATEGORY = "fastlife"
56
58
 
@@ -260,7 +262,14 @@ class GenericConfigurator(Generic[TRegistry]):
260
262
  self._route_prefix = old
261
263
  return self
262
264
 
263
- def set_locale_negociator(self, locale_negociator: LocaleNegociator) -> Self:
265
+ def set_request_factory(
266
+ self, request_factory: "RequestFactoryBuilder[TRegistry]"
267
+ ) -> Self:
268
+ """Install a request factory, to use a custom request classes."""
269
+ self.registry.request_factory = request_factory(self.registry)
270
+ return self
271
+
272
+ def set_locale_negociator(self, locale_negociator: "LocaleNegociator") -> Self:
264
273
  """Install a locale negociator for the app."""
265
274
  self.registry.locale_negociator = locale_negociator
266
275
  return self
@@ -1,3 +1,21 @@
1
+ """ASGI types from Starlette."""
2
+
3
+ from starlette.requests import Request
4
+ from starlette.responses import Response
1
5
  from starlette.types import ASGIApp, Message, Receive, Scope, Send
2
6
 
3
- __all__ = ["ASGIApp", "Message", "Receive", "Scope", "Send"]
7
+ ASGIRequest = Request
8
+ """Starlette request class used as ASGI Protocol base HTTP Request representation."""
9
+
10
+ ASGIResponse = Response
11
+ """Starlette request class used as ASGI Protocol base HTTP Response representation."""
12
+
13
+ __all__ = [
14
+ "ASGIApp",
15
+ "ASGIRequest",
16
+ "ASGIResponse",
17
+ "Message",
18
+ "Receive",
19
+ "Scope",
20
+ "Send",
21
+ ]
@@ -58,7 +58,8 @@ class FormModel(Generic[T]):
58
58
  cls, prefix: str, pydantic_type: type[T], data: Mapping[str, Any]
59
59
  ) -> "FormModel[T]":
60
60
  try:
61
- return cls(prefix, pydantic_type(**data.get(prefix, {})), {}, True)
61
+ ret = cls(prefix, pydantic_type(**data.get(prefix, {})), {}, True)
62
+ return ret
62
63
  except ValidationError as exc:
63
64
  errors: dict[str, str] = {}
64
65
  for error in exc.errors():
@@ -2,8 +2,7 @@
2
2
 
3
3
  from typing import TYPE_CHECKING, Any, Generic
4
4
 
5
- from starlette.requests import Request as BaseRequest
6
-
5
+ from fastlife.domain.model.asgi import ASGIRequest
7
6
  from fastlife.domain.model.csrf import CSRFToken, create_csrf_token
8
7
  from fastlife.domain.model.security_policy import TClaimedIdentity, TIdentity
9
8
  from fastlife.service.registry import TRegistry
@@ -15,7 +14,7 @@ if TYPE_CHECKING:
15
14
  )
16
15
 
17
16
 
18
- class GenericRequest(BaseRequest, Generic[TRegistry, TIdentity, TClaimedIdentity]):
17
+ class GenericRequest(ASGIRequest, Generic[TRegistry, TIdentity, TClaimedIdentity]):
19
18
  """HTTP Request representation."""
20
19
 
21
20
  registry: TRegistry
@@ -30,7 +29,7 @@ class GenericRequest(BaseRequest, Generic[TRegistry, TIdentity, TClaimedIdentity
30
29
 
31
30
  renderer_globals: dict[str, Any]
32
31
 
33
- def __init__(self, registry: TRegistry, request: BaseRequest) -> None:
32
+ def __init__(self, registry: TRegistry, request: ASGIRequest) -> None:
34
33
  super().__init__(request.scope, request.receive)
35
34
  self.registry = registry
36
35
  self.locale_name = registry.locale_negociator(self)
@@ -17,8 +17,8 @@ class SessionMiddleware(AbstractMiddleware):
17
17
 
18
18
  def __init__(
19
19
  self,
20
- *,
21
20
  app: ASGIApp,
21
+ *,
22
22
  cookie_name: str,
23
23
  secret_key: str,
24
24
  duration: timedelta,
@@ -0,0 +1 @@
1
+ """A collection of service."""
@@ -1,4 +1,4 @@
1
- """Security policy."""
1
+ """Security policy permission routine."""
2
2
 
3
3
  from collections.abc import Callable, Coroutine
4
4
  from typing import Any
@@ -8,12 +8,10 @@ from fastlife.settings import Settings
8
8
  LocaleName = str
9
9
  """The LocaleName is a locale such as en, fr that will be consume for translations."""
10
10
 
11
- from fastlife.adapters.fastapi.request import GenericRequest # coverage: ignore
11
+ from fastlife.adapters.fastapi.request import GenericRequest
12
12
 
13
- LocaleNegociator = Callable[
14
- [GenericRequest[Any, Any, Any]], LocaleName
15
- ] # coverage: ignore
16
- """Interface to implement to negociate a locale""" # coverage: ignore
13
+ LocaleNegociator = Callable[[GenericRequest[Any, Any, Any]], LocaleName]
14
+ """Interface to implement to negociate a locale"""
17
15
 
18
16
 
19
17
  def default_negociator(settings: Settings) -> LocaleNegociator:
@@ -1,3 +1,5 @@
1
+ """Application registry."""
2
+
1
3
  from collections.abc import AsyncIterator, Mapping
2
4
  from contextlib import asynccontextmanager
3
5
  from typing import TYPE_CHECKING, Any, Generic, TypeVar
@@ -6,6 +8,7 @@ from fastapi import FastAPI
6
8
 
7
9
  if TYPE_CHECKING:
8
10
  from fastlife.service.locale_negociator import LocaleNegociator # coverage: ignore
11
+ from fastlife.service.request_factory import RequestFactory # coverage: ignore
9
12
  from fastlife.service.templates import ( # coverage: ignore
10
13
  AbstractTemplateRendererFactory, # coverage: ignore
11
14
  ) # coverage: ignore
@@ -33,15 +36,18 @@ class GenericRegistry(Generic[TSettings]):
33
36
  """Used to fine the best language for the response."""
34
37
  localizer: "LocalizerFactory"
35
38
  """Used to localized message."""
39
+ request_factory: "RequestFactory"
36
40
 
37
41
  def __init__(self, settings: TSettings) -> None:
38
42
  from fastlife.service.locale_negociator import default_negociator
43
+ from fastlife.service.request_factory import default_request_factory
39
44
  from fastlife.service.translations import LocalizerFactory
40
45
 
41
46
  self.settings = settings
42
47
  self.locale_negociator = default_negociator(self.settings)
43
48
  self.renderers = {}
44
49
  self.localizer = LocalizerFactory()
50
+ self.request_factory = default_request_factory(self)
45
51
 
46
52
  def get_renderer(self, template: str) -> "AbstractTemplateRendererFactory":
47
53
  for key, val in self.renderers.items():
@@ -0,0 +1,26 @@
1
+ """Customize the request class."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any
5
+
6
+ from fastlife.domain.model.asgi import ASGIRequest
7
+ from fastlife.domain.model.request import GenericRequest
8
+ from fastlife.service.registry import DefaultRegistry, TRegistry
9
+
10
+ RequestFactory = Callable[[ASGIRequest], GenericRequest[Any, Any, Any]]
11
+ """
12
+ Transform the [ASGIRequest](#fastlife.domain.model.asgi.ASGIRequest)
13
+ object to the fastlife [GenericRequest](#fastlife.domain.model.request.GenericRequest).
14
+ """
15
+
16
+ RequestFactoryBuilder = Callable[[TRegistry], RequestFactory]
17
+ """Interface to implement to create a request factory"""
18
+
19
+
20
+ def default_request_factory(registry: DefaultRegistry) -> RequestFactory:
21
+ """The default request factory the return the generic request."""
22
+
23
+ def request(request: ASGIRequest) -> GenericRequest[Any, Any, Any]:
24
+ return GenericRequest[Any, Any, Any](registry, request)
25
+
26
+ return request
@@ -1,3 +1,5 @@
1
+ """Implement i18n."""
2
+
1
3
  import pathlib
2
4
  from collections import defaultdict
3
5
  from collections.abc import Callable, Iterator
@@ -15,7 +17,7 @@ class TranslatableString(str):
15
17
  """
16
18
  Create a string made for translation associated to a domain.
17
19
  This class is instanciated by the
18
- :class:`fastlife.service.translations.TranslatableStringFactory` class.
20
+ {class}`fastlife.service.translations.TranslatableStringFactory` class.
19
21
  """
20
22
 
21
23
  __slots__ = ("domain",)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastlifeweb
3
- Version: 0.25.1
3
+ Version: 0.26.0
4
4
  Summary: High-level web framework
5
5
  Author-Email: Guillaume Gauvrit <guillaume@gauvr.it>
6
6
  License: MIT
@@ -17,14 +17,14 @@ Project-URL: Repository, https://github.com/mardiros/fastlife.git
17
17
  Project-URL: Issues, https://github.com/mardiros/fastlife/issues
18
18
  Project-URL: Changelog, https://mardiros.github.io/fastlife/user/changelog.html
19
19
  Requires-Python: >=3.11
20
- Requires-Dist: fastapi[standard]<1,>=0.115.0
20
+ Requires-Dist: fastapi[standard]<0.116.0,>=0.115.4
21
21
  Requires-Dist: itsdangerous<3,>=2.1.2
22
- Requires-Dist: jinjax<0.45,>=0.44
22
+ Requires-Dist: jinjax<0.49,>=0.48
23
23
  Requires-Dist: markupsafe<3,>=2.1.3
24
24
  Requires-Dist: multidict<7,>=6.0.5
25
25
  Requires-Dist: pydantic<3,>=2.5.3
26
26
  Requires-Dist: pydantic-settings<3,>=2.0.3
27
- Requires-Dist: python-multipart<1,>=0.0.9
27
+ Requires-Dist: python-multipart<1,>=0.0.13
28
28
  Requires-Dist: venusian<4,>=3.0.0
29
29
  Provides-Extra: testing
30
30
  Requires-Dist: beautifulsoup4; extra == "testing"
@@ -1,5 +1,5 @@
1
- CHANGELOG.md,sha256=5xcrgdVtnurPhs6LZ9zKuTIedXPWQvEilOVpamvD2BE,8279
2
- fastlife/__init__.py,sha256=nXWE4AbhkhG_yBjPJU-XnKDMTsU9ebv7Vj4eIciWQI0,2219
1
+ CHANGELOG.md,sha256=H7i2AY7B5DYbr5ACg2YRaTCO8vWtQMGAMw7bkg2DHhA,8594
2
+ fastlife/__init__.py,sha256=IZ9VQvlBduZ3WjfDk05rZNdCKNxWWqPaMvG0ZWtMTpU,2489
3
3
  fastlife/adapters/__init__.py,sha256=imPD1hImpgrYkvUJRhHA5kVyGAua7VbP2WGkhSWKJT8,93
4
4
  fastlife/adapters/fastapi/__init__.py,sha256=1goV1FGFP04TGyskJBLKZam4Gvt1yoAvLMNs4ekWSSQ,243
5
5
  fastlife/adapters/fastapi/form.py,sha256=csxsDI6RK-g41pMwFhaVQCLDhF7dAZzgUp-VcrC3NFY,823
@@ -7,7 +7,7 @@ fastlife/adapters/fastapi/form_data.py,sha256=2DQ0o-RvY6iROUKQjS-UJdNYEVSsNPd-Aj
7
7
  fastlife/adapters/fastapi/localizer.py,sha256=Efn6rrf-SnSfM4TqqE_5chacrxaPpupxbvIqXipXEEw,448
8
8
  fastlife/adapters/fastapi/request.py,sha256=COOoSMZAm4VhyJgM7dlqJ7YdGjeGI7qs93PtBsriEPc,1115
9
9
  fastlife/adapters/fastapi/routing/__init__.py,sha256=8EMnQE5n8oA4J9_c3nxzwKDVt3tefZ6fGH0d2owE8mo,195
10
- fastlife/adapters/fastapi/routing/route.py,sha256=XnDPvd5V0Zl7Ke6bBErEtUCjmNQPcV2U_w1dWpx6qM4,1476
10
+ fastlife/adapters/fastapi/routing/route.py,sha256=33nk0mf9eTOrdyQfeoOGOs5153TzT227sem0THWvr8k,1367
11
11
  fastlife/adapters/fastapi/routing/router.py,sha256=jzrnU_Lyywu21e3spPaWQw8ujZh_Yy_EJOojcCi6ew4,499
12
12
  fastlife/adapters/itsdangerous/__init__.py,sha256=7ocGY7v0cxooZBKQYjA2JkmzRqiBvcU1uzA84UsTVAI,84
13
13
  fastlife/adapters/itsdangerous/session.py,sha256=9h_WRsXqZbytHZOv5B_K3OWD5mbfYzxHulXoOf6D2MI,1685
@@ -39,8 +39,8 @@ fastlife/adapters/jinjax/widgets/dropdown.py,sha256=ou8U48txShr8IXdwF4_pBvTn1VcR
39
39
  fastlife/adapters/jinjax/widgets/hidden.py,sha256=IKcVYs6NjN8YjW-UTr3DRBong6Wrc0QLgcp8U9JoQmE,638
40
40
  fastlife/adapters/jinjax/widgets/mfa_code.py,sha256=8HHaEHyUEQT6xzJ0Y4O0eA1SU3wSfzXljx8XY73o-Rc,733
41
41
  fastlife/adapters/jinjax/widgets/model.py,sha256=YBIEWa_6mnmrBnesXjLTrpJ4drUS2CIorNmhK24cz7Q,1298
42
- fastlife/adapters/jinjax/widgets/sequence.py,sha256=XhIPRJyE9UXFetlDQA83N64kKlTqkj6WPcgPm6XF7mo,2559
43
- fastlife/adapters/jinjax/widgets/text.py,sha256=sA-TMRP5AqxhN1tLbV_OZ7xbvRip4aNNQVWZesnOawg,3024
42
+ fastlife/adapters/jinjax/widgets/sequence.py,sha256=dVoHQmHloaRuU1Sd82b2jnO8WDfdwM2FaZlLCJCps1o,2566
43
+ fastlife/adapters/jinjax/widgets/text.py,sha256=TfmlJU233aZWIl-4cmm-f-pFxp6ycHWHnbiluOvRDgM,3040
44
44
  fastlife/adapters/jinjax/widgets/union.py,sha256=roCoFA82dLjF1XFW6UYaV7SCQWdFsSAT8Ux7KEB6_Us,2602
45
45
  fastlife/assets/dist.css,sha256=BkGYK48Fmy7t3-KMKlpGnpjmpJpxQ4D6QUNlfmtVbU8,18432
46
46
  fastlife/assets/source.css,sha256=0KtDcsKHj9LOcqNR1iv9pACwNBaNWkieEDqqjkgNL_s,47
@@ -1690,17 +1690,17 @@ fastlife/components/pydantic_form/FatalError.jinja,sha256=ADtQvmo-e-NmDcFM1E6wZV
1690
1690
  fastlife/components/pydantic_form/Hint.jinja,sha256=8leBpfMGDmalc_KAjr2paTojr_rwq-luS6m_1BGj7Tw,202
1691
1691
  fastlife/components/pydantic_form/Widget.jinja,sha256=PgguUpvhG6CY9AW6H8qQMjKqjlybjDCAaFFAOHzrzVQ,418
1692
1692
  fastlife/config/__init__.py,sha256=5qpuaVYqi-AS0GgsfggM6rFsSwXgrqrLBo9jH6dVroc,407
1693
- fastlife/config/configurator.py,sha256=wlgSfbKoeBzk5kmCnftmrgVV8CWQhxoioBZeuRTPZ64,24779
1693
+ fastlife/config/configurator.py,sha256=200Vk4Tm7jv8XFWTFDYNUyuB9bDEcrJOnmtVyBItVVA,25188
1694
1694
  fastlife/config/exceptions.py,sha256=9MdBnbfy-Aw-KaIFzju0Kh8Snk41-v9LqK2w48Tdy1s,1169
1695
1695
  fastlife/config/openapiextra.py,sha256=rYoerrn9sni2XwnO3gIWqaz7M0aDZPhVLjzqhDxue0o,514
1696
1696
  fastlife/config/resources.py,sha256=EcPTM25pnHcGFTtXjeZnWn5Mo_-8rhJ72HJ6rxnjPg8,8389
1697
1697
  fastlife/config/views.py,sha256=9CZ0qNi8vKvQuGo1GgM6cwNK8WwHOxwIHqtikAOaOHY,2399
1698
1698
  fastlife/domain/__init__.py,sha256=3zDDos5InVX0el9OO0lgSDGzdUNYIhlA6w4uhBh2pF8,29
1699
1699
  fastlife/domain/model/__init__.py,sha256=aoBjaSpDscuFXvtknJHwiNyoJRUpE-v4X54h_wNuo2Y,27
1700
- fastlife/domain/model/asgi.py,sha256=RSTnfTsofOmCaWzHNuRGowjlyHYmoDCrXFbvNY_B55k,129
1700
+ fastlife/domain/model/asgi.py,sha256=Cz45TZOtrh2pBVZr37aJ9jpnJH9BeNHrsvk9bq1nBc0,526
1701
1701
  fastlife/domain/model/csrf.py,sha256=BUiWK-S7rVciWHO1qTkM8e_KxzpF6gGC4MMJK1v6iDo,414
1702
- fastlife/domain/model/form.py,sha256=WriBT1qUUIbf5x5iewo9ChEcr6k0en8jMTD0iaei5Pk,3253
1703
- fastlife/domain/model/request.py,sha256=ZRHZW_MOmtO_DFHt2UYu_aUmtoMdD14085A8Z8_eS8s,2678
1702
+ fastlife/domain/model/form.py,sha256=JP6uumlZBYhiPxzcdxOsfsFm5BRfvkDFvlUCD6Vy8dI,3275
1703
+ fastlife/domain/model/request.py,sha256=HgUSnUu3q18e07y57PadN3pPQwYrIZS1YEhYkBZ_Zfg,2674
1704
1704
  fastlife/domain/model/security_policy.py,sha256=f9SLi54vvRU-KSPJ5K0unoqYpkxIyzuZjKf2Ylwf5Rg,4796
1705
1705
  fastlife/domain/model/template.py,sha256=z9oxdKme1hMPuvk7mBiKR_tuVY8TqH77aTYqMgvEGl8,876
1706
1706
  fastlife/domain/model/types.py,sha256=64jJKFAi5x0e3vr8naHU1m_as0Qy8MS-s9CG0z6K1qc,381
@@ -1709,18 +1709,18 @@ fastlife/middlewares/base.py,sha256=7FZE_1YU7wNew2u1qdYXjamosk4CXJmg1mJWGp6Xhc0,
1709
1709
  fastlife/middlewares/reverse_proxy/__init__.py,sha256=g1SoVDmenKzpAAPYHTEsWgdBByOxtLg9fGx6RV3i0ok,846
1710
1710
  fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=PPDjcfwik5eoYaolSY1Y4x5QMKpDV0XrOP_i4Am0y30,1724
1711
1711
  fastlife/middlewares/session/__init__.py,sha256=ZhXWXs53A__F9wJKBJ87rW8Qyt5Mn866vhzKDxVZ4t0,1348
1712
- fastlife/middlewares/session/middleware.py,sha256=MyZ0MobhlnGiqacYq0pPYBrlqCjTkWjpNXNeFyPD1fI,3133
1712
+ fastlife/middlewares/session/middleware.py,sha256=tzaJHLT3ri9sstrppATu8MWXUALTq54PsNKU0v5DTBI,3133
1713
1713
  fastlife/middlewares/session/serializer.py,sha256=nbJGiCJ_ryZxkW1I28kmK6hD3U98D4ZlUQA7B8_tngQ,635
1714
1714
  fastlife/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1715
- fastlife/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1716
- fastlife/service/check_permission.py,sha256=-TsI58YZJtWIw5bsm0fVpfuaCMUx4cmoLTKGXeyQPDk,1809
1715
+ fastlife/service/__init__.py,sha256=SfM2eSrMjDx6safjBc2LVFty4Wy2H1ZsHQSHeDcZ7dU,31
1716
+ fastlife/service/check_permission.py,sha256=WodiDVTnY-dZmTfbQV-YmJfPOLtE07mfqvG6jvL0xeA,1828
1717
1717
  fastlife/service/csrf.py,sha256=wC1PaKOmZ3il0FF_kevxnlg9PxDqruRdLrNnOA3ZHrU,1886
1718
- fastlife/service/locale_negociator.py,sha256=JUqzTukxDqTJVOR-CNI7Vqo6kvdvwxYvZQe8P3V9S2U,796
1719
- fastlife/service/registry.py,sha256=3lm7aUD7FdlV1lQUS73OuBlL55-O1DulPJdE0n6Epks,2648
1718
+ fastlife/service/locale_negociator.py,sha256=4HifgNkyI7DxR3_IdSUMG0UUY-JZeQsJ_MMSqiyFzgc,730
1719
+ fastlife/service/registry.py,sha256=0r8dVCF44JUugRctL9sDQjnHDV7SepH06OfkV6KE-4s,2937
1720
+ fastlife/service/request_factory.py,sha256=9o4B_78qrKPXQAq8A_RDhzAqCHdt6arV96Bq_JByyIM,931
1720
1721
  fastlife/service/security_policy.py,sha256=qYXs4mhfz_u4x59NhUkirqKYKQbFv9YrzyRuXj7mxE0,4688
1721
1722
  fastlife/service/templates.py,sha256=xNMKH-jNkEoCscO04H-QlzTqg-0pYbF_fc65xG-2rzs,2575
1722
- fastlife/service/translatablestring.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
1723
- fastlife/service/translations.py,sha256=s6qFZSXR-1vYxSr7RRH-mS-VjNaa8OTxR7-k6Ib7h0E,6878
1723
+ fastlife/service/translations.py,sha256=cAfvUlLM3KcgQjlD9PtEpZpTMctXKM_CUAmUeKw9n4M,6901
1724
1724
  fastlife/settings.py,sha256=q-rz4CEF2RQGow5-m-yZJOvdh3PPb2c1Q_ZLJGnu4VQ,3647
1725
1725
  fastlife/shared_utils/__init__.py,sha256=i66ytuf-Ezo7jSiNQHIsBMVIcB-tDX0tg28-pUOlhzE,26
1726
1726
  fastlife/shared_utils/infer.py,sha256=0GflLkaWJ-4LZ1Ig3moR-_o55wwJ_p_vJ4xo-yi3lyA,1406
@@ -1733,8 +1733,8 @@ fastlife/testing/session.py,sha256=LEFFbiR67_x_g-ioudkY0C7PycHdbDfaIaoo_G7GXQ8,2
1733
1733
  fastlife/testing/testclient.py,sha256=Id1tlA1ZapyW-8kUh2_U3lLteL64m3ERqOO7NAN7HEY,6922
1734
1734
  fastlife/views/__init__.py,sha256=zG8gveL8e2zBdYx6_9jtZfpQ6qJT-MFnBY3xXkLwHZI,22
1735
1735
  fastlife/views/pydantic_form.py,sha256=o7EUItciAGL1OSaGNHo-3BTrYAk34GuWE7zGikjiAGY,1486
1736
- fastlifeweb-0.25.1.dist-info/METADATA,sha256=PFDjQi6FjZXjexLeQspAbz8cbA8NtKX2jCzpflgyujk,3683
1737
- fastlifeweb-0.25.1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1738
- fastlifeweb-0.25.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1739
- fastlifeweb-0.25.1.dist-info/licenses/LICENSE,sha256=JFWuiKYRXKKMEAsX0aZp3hBcju-HYflJ2rwJAGwbCJo,1080
1740
- fastlifeweb-0.25.1.dist-info/RECORD,,
1736
+ fastlifeweb-0.26.0.dist-info/METADATA,sha256=iCt6oKseeHBfQyuoiUuUXK4p-ls8QM4wzkA8JdiPXIk,3690
1737
+ fastlifeweb-0.26.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1738
+ fastlifeweb-0.26.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1739
+ fastlifeweb-0.26.0.dist-info/licenses/LICENSE,sha256=JFWuiKYRXKKMEAsX0aZp3hBcju-HYflJ2rwJAGwbCJo,1080
1740
+ fastlifeweb-0.26.0.dist-info/RECORD,,
@@ -1 +0,0 @@
1
-