fastlifeweb 0.23.1__py3-none-any.whl → 0.24.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,6 @@
1
+ ## 0.24.0 - Released on 2025-01-17
2
+ * Add a way to hook the lifespan to the app
3
+
1
4
  ## 0.23.1 - Released on 2025-01-14
2
5
  * Fix typing issue
3
6
  * Update docs
@@ -191,6 +191,7 @@ class GenericConfigurator(Generic[TRegistry]):
191
191
  dependencies=[Depends(check_csrf())],
192
192
  docs_url=self.api_swagger_ui_url,
193
193
  redoc_url=self.api_redoc_url,
194
+ lifespan=self.registry.lifespan,
194
195
  openapi_tags=[tag.model_dump(by_alias=True) for tag in self.tags.values()]
195
196
  if self.tags
196
197
  else None,
@@ -124,13 +124,7 @@ def resource(
124
124
  config, method, collection_path, getattr(api, method)
125
125
  )
126
126
  case (
127
- "get"
128
- | "post"
129
- | "put"
130
- | "patch"
131
- | "delete"
132
- | "head"
133
- | "options"
127
+ "get" | "post" | "put" | "patch" | "delete" | "head" | "options"
134
128
  ):
135
129
  bind_config(config, method, path, getattr(api, method))
136
130
  case _:
@@ -72,7 +72,7 @@ class SessionMiddleware(AbstractMiddleware):
72
72
  headers = MutableHeaders(scope=message)
73
73
  expires = "expires=Thu, 01 Jan 1970 00:00:00 GMT; "
74
74
  header_value = (
75
- f"{self.cookie_name}=; " f"{expires}{self.security_flags}"
75
+ f"{self.cookie_name}=; {expires}{self.security_flags}"
76
76
  )
77
77
  headers.append("set-cookie", header_value)
78
78
  await send(message)
@@ -1,5 +1,8 @@
1
- from collections.abc import Mapping
2
- from typing import TYPE_CHECKING, Generic, TypeVar
1
+ from collections.abc import AsyncIterator, Mapping
2
+ from contextlib import asynccontextmanager
3
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
4
+
5
+ from fastapi import FastAPI
3
6
 
4
7
  if TYPE_CHECKING:
5
8
  from fastlife.service.locale_negociator import LocaleNegociator # coverage: ignore
@@ -46,6 +49,19 @@ class GenericRegistry(Generic[TSettings]):
46
49
  return val
47
50
  raise RuntimeError(f"No renderer registered for template {template}")
48
51
 
52
+ @asynccontextmanager
53
+ async def lifespan(self, app: FastAPI) -> AsyncIterator[Any]:
54
+ """
55
+ hook to override the lifespan of the starlette app.
56
+
57
+ The [lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)
58
+ is used to initialized and dispose the application state.
59
+
60
+ In fastlife the application state is the registry, it has to be overriden
61
+ to add an implementation.
62
+ """
63
+ yield
64
+
49
65
 
50
66
  DefaultRegistry = GenericRegistry[Settings]
51
67
  """
fastlife/testing/form.py CHANGED
@@ -109,7 +109,7 @@ class WebForm:
109
109
  raise ValueError(f'"{fieldname}" does not exists')
110
110
  field = self._formfields[fieldname]
111
111
  if field.node_name != "select":
112
- raise ValueError(f"{fieldname} is a {field!r}, " "use set() instead")
112
+ raise ValueError(f"{fieldname} is a {field!r}, use set() instead")
113
113
 
114
114
  for option in field.by_node_name("option"):
115
115
  if option.text == value.strip():
@@ -1,7 +1,7 @@
1
1
  """Testing your application."""
2
2
 
3
3
  from collections.abc import Mapping, MutableMapping
4
- from typing import Any, Literal
4
+ from typing import Any, Literal, Self
5
5
  from urllib.parse import urlencode
6
6
 
7
7
  import bs4
@@ -208,3 +208,10 @@ class WebTestClient:
208
208
  headers={"Content-Type": "application/x-www-form-urlencoded", **headers},
209
209
  max_redirects=int(follow_redirects) * 10,
210
210
  )
211
+
212
+ def __enter__(self) -> Self:
213
+ self.testclient.__enter__()
214
+ return self
215
+
216
+ def __exit__(self, *args: Any, **kwargs: Any) -> None:
217
+ self.testclient.__exit__()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastlifeweb
3
- Version: 0.23.1
3
+ Version: 0.24.0
4
4
  Summary: High-level web framework
5
5
  Author-Email: Guillaume Gauvrit <guillaume@gauvr.it>
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- CHANGELOG.md,sha256=gvl1gBNgVNhdz4fSMSIsPwWpArqetbDebCW2PAB6yoE,7871
1
+ CHANGELOG.md,sha256=1gHbqLrx79ltwysUaPw25Sp6Aqz5nbyZK_qcgJxc6Og,7952
2
2
  fastlife/__init__.py,sha256=nXWE4AbhkhG_yBjPJU-XnKDMTsU9ebv7Vj4eIciWQI0,2219
3
3
  fastlife/adapters/__init__.py,sha256=imPD1hImpgrYkvUJRhHA5kVyGAua7VbP2WGkhSWKJT8,93
4
4
  fastlife/adapters/fastapi/__init__.py,sha256=1goV1FGFP04TGyskJBLKZam4Gvt1yoAvLMNs4ekWSSQ,243
@@ -1686,10 +1686,10 @@ fastlife/components/pydantic_form/FatalError.jinja,sha256=lFVlNrXzBR6ExMahq77h0t
1686
1686
  fastlife/components/pydantic_form/Hint.jinja,sha256=8leBpfMGDmalc_KAjr2paTojr_rwq-luS6m_1BGj7Tw,202
1687
1687
  fastlife/components/pydantic_form/Widget.jinja,sha256=PgguUpvhG6CY9AW6H8qQMjKqjlybjDCAaFFAOHzrzVQ,418
1688
1688
  fastlife/config/__init__.py,sha256=5qpuaVYqi-AS0GgsfggM6rFsSwXgrqrLBo9jH6dVroc,407
1689
- fastlife/config/configurator.py,sha256=gxa3aTfBXvGqRLLAaZ0CoNAjwHlQIhx4yr1DfY_z2IQ,24734
1689
+ fastlife/config/configurator.py,sha256=wlgSfbKoeBzk5kmCnftmrgVV8CWQhxoioBZeuRTPZ64,24779
1690
1690
  fastlife/config/exceptions.py,sha256=9MdBnbfy-Aw-KaIFzju0Kh8Snk41-v9LqK2w48Tdy1s,1169
1691
1691
  fastlife/config/openapiextra.py,sha256=rYoerrn9sni2XwnO3gIWqaz7M0aDZPhVLjzqhDxue0o,514
1692
- fastlife/config/resources.py,sha256=u6OgnbHfGkC5idH-YPNkIPf8GJnZpJoGVZ-Ym022BCo,8533
1692
+ fastlife/config/resources.py,sha256=EcPTM25pnHcGFTtXjeZnWn5Mo_-8rhJ72HJ6rxnjPg8,8389
1693
1693
  fastlife/config/views.py,sha256=9CZ0qNi8vKvQuGo1GgM6cwNK8WwHOxwIHqtikAOaOHY,2399
1694
1694
  fastlife/domain/__init__.py,sha256=3zDDos5InVX0el9OO0lgSDGzdUNYIhlA6w4uhBh2pF8,29
1695
1695
  fastlife/domain/model/__init__.py,sha256=aoBjaSpDscuFXvtknJHwiNyoJRUpE-v4X54h_wNuo2Y,27
@@ -1705,14 +1705,14 @@ fastlife/middlewares/base.py,sha256=7FZE_1YU7wNew2u1qdYXjamosk4CXJmg1mJWGp6Xhc0,
1705
1705
  fastlife/middlewares/reverse_proxy/__init__.py,sha256=g1SoVDmenKzpAAPYHTEsWgdBByOxtLg9fGx6RV3i0ok,846
1706
1706
  fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=PPDjcfwik5eoYaolSY1Y4x5QMKpDV0XrOP_i4Am0y30,1724
1707
1707
  fastlife/middlewares/session/__init__.py,sha256=ZhXWXs53A__F9wJKBJ87rW8Qyt5Mn866vhzKDxVZ4t0,1348
1708
- fastlife/middlewares/session/middleware.py,sha256=ituZ5hNipDMkgCXNE4zbnmOcWEF151sucPo4I_FpY-I,3137
1708
+ fastlife/middlewares/session/middleware.py,sha256=MyZ0MobhlnGiqacYq0pPYBrlqCjTkWjpNXNeFyPD1fI,3133
1709
1709
  fastlife/middlewares/session/serializer.py,sha256=nbJGiCJ_ryZxkW1I28kmK6hD3U98D4ZlUQA7B8_tngQ,635
1710
1710
  fastlife/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1711
1711
  fastlife/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1712
1712
  fastlife/service/check_permission.py,sha256=-TsI58YZJtWIw5bsm0fVpfuaCMUx4cmoLTKGXeyQPDk,1809
1713
1713
  fastlife/service/csrf.py,sha256=wC1PaKOmZ3il0FF_kevxnlg9PxDqruRdLrNnOA3ZHrU,1886
1714
1714
  fastlife/service/locale_negociator.py,sha256=JUqzTukxDqTJVOR-CNI7Vqo6kvdvwxYvZQe8P3V9S2U,796
1715
- fastlife/service/registry.py,sha256=sdLJ-1K7R1_RwVNpQUcyktPOORhDm_pyKw8jehhR5VM,2100
1715
+ fastlife/service/registry.py,sha256=3lm7aUD7FdlV1lQUS73OuBlL55-O1DulPJdE0n6Epks,2648
1716
1716
  fastlife/service/security_policy.py,sha256=qYXs4mhfz_u4x59NhUkirqKYKQbFv9YrzyRuXj7mxE0,4688
1717
1717
  fastlife/service/templates.py,sha256=QPAIUbbZiekazz_jV3q4JCwQd6Q4KA6a4RDek2RWuhE,2548
1718
1718
  fastlife/service/translatablestring.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
@@ -1724,14 +1724,14 @@ fastlife/shared_utils/resolver.py,sha256=Wb9cO2MWavpti63hju15xmwFMgaD5DsQaxikRpB
1724
1724
  fastlife/template_globals.py,sha256=rJ7XB9DlPubejs_GDlEyO9V98QZTJnmdTznlguYOyoc,8386
1725
1725
  fastlife/testing/__init__.py,sha256=VpxkS3Zp3t_hH8dBiLaGFGhsvt511dhBS_8fMoFXdmU,99
1726
1726
  fastlife/testing/dom.py,sha256=dVzDoZokn-ii681UaEwAr-khM5KE-CHgXSSLSo24oH0,4489
1727
- fastlife/testing/form.py,sha256=ST0xNCoUqz_oD92cWHzQ6CbJ5hFopvu_NNKpOfiuYWY,7874
1727
+ fastlife/testing/form.py,sha256=diiGfVMfNt19JTNUxlnbGfcbskR3ZMpk0Y-A57vfShc,7871
1728
1728
  fastlife/testing/session.py,sha256=LEFFbiR67_x_g-ioudkY0C7PycHdbDfaIaoo_G7GXQ8,2226
1729
- fastlife/testing/testclient.py,sha256=TWGbxagxwFEm7_SooItjLchhF5ptHwhyKUh7uhWN_CA,6731
1729
+ fastlife/testing/testclient.py,sha256=Id1tlA1ZapyW-8kUh2_U3lLteL64m3ERqOO7NAN7HEY,6922
1730
1730
  fastlife/views/__init__.py,sha256=zG8gveL8e2zBdYx6_9jtZfpQ6qJT-MFnBY3xXkLwHZI,22
1731
1731
  fastlife/views/pydantic_form.py,sha256=o7EUItciAGL1OSaGNHo-3BTrYAk34GuWE7zGikjiAGY,1486
1732
- fastlifeweb-0.23.1.dist-info/METADATA,sha256=O3yeVKCL9s-zEyG6Gsl6Z8UmrX9T9cMwkkOgz0bkw58,3663
1733
- fastlifeweb-0.23.1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1734
- fastlifeweb-0.23.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1735
- fastlifeweb-0.23.1.dist-info/licenses/LICENSE,sha256=NlRX9Z-dcv8X1VFW9odlIQBbgNN9pcO94XzvKp2R16o,1075
1732
+ fastlifeweb-0.24.0.dist-info/METADATA,sha256=a4Pp2mA7yCIvBnvF7Jrrt0jzQRX7ousymKDpb1slGfY,3663
1733
+ fastlifeweb-0.24.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1734
+ fastlifeweb-0.24.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1735
+ fastlifeweb-0.24.0.dist-info/licenses/LICENSE,sha256=NlRX9Z-dcv8X1VFW9odlIQBbgNN9pcO94XzvKp2R16o,1075
1736
1736
  tailwind.config.js,sha256=EN3EahBDmQBbmJvkw3SdGWNOkfkzw0cg-QvBikOhkrw,1348
1737
- fastlifeweb-0.23.1.dist-info/RECORD,,
1737
+ fastlifeweb-0.24.0.dist-info/RECORD,,