fastlifeweb 0.23.1__py3-none-any.whl → 0.25.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 +6 -0
- fastlife/config/configurator.py +1 -0
- fastlife/config/resources.py +1 -7
- fastlife/middlewares/session/middleware.py +1 -1
- fastlife/service/registry.py +18 -2
- fastlife/template_globals.py +5 -5
- fastlife/testing/form.py +1 -1
- fastlife/testing/testclient.py +8 -1
- {fastlifeweb-0.23.1.dist-info → fastlifeweb-0.25.0.dist-info}/METADATA +3 -2
- {fastlifeweb-0.23.1.dist-info → fastlifeweb-0.25.0.dist-info}/RECORD +13 -14
- {fastlifeweb-0.23.1.dist-info → fastlifeweb-0.25.0.dist-info}/licenses/LICENSE +1 -1
- tailwind.config.js +0 -57
- {fastlifeweb-0.23.1.dist-info → fastlifeweb-0.25.0.dist-info}/WHEEL +0 -0
- {fastlifeweb-0.23.1.dist-info → fastlifeweb-0.25.0.dist-info}/entry_points.txt +0 -0
CHANGELOG.md
CHANGED
fastlife/config/configurator.py
CHANGED
@@ -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,
|
fastlife/config/resources.py
CHANGED
@@ -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}=;
|
75
|
+
f"{self.cookie_name}=; {expires}{self.security_flags}"
|
76
76
|
)
|
77
77
|
headers.append("set-cookie", header_value)
|
78
78
|
await send(message)
|
fastlife/service/registry.py
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
from collections.abc import Mapping
|
2
|
-
from
|
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/template_globals.py
CHANGED
@@ -39,7 +39,7 @@ class Globals(BaseModel):
|
|
39
39
|
"text-white",
|
40
40
|
"hover:bg-primary-700",
|
41
41
|
"hover:bg-primary-200",
|
42
|
-
"focus:outline-
|
42
|
+
"focus:outline-hidden",
|
43
43
|
"focus:ring-4",
|
44
44
|
"focus:ring-primary-300",
|
45
45
|
"dark:bg-primary-600",
|
@@ -60,7 +60,7 @@ class Globals(BaseModel):
|
|
60
60
|
"text-center",
|
61
61
|
"text-neutral-900",
|
62
62
|
"text-sm",
|
63
|
-
"focus:outline-
|
63
|
+
"focus:outline-hidden",
|
64
64
|
"focus:ring-4",
|
65
65
|
"focus:ring-primary-300",
|
66
66
|
"hover:bg-neutral-200",
|
@@ -81,12 +81,12 @@ class Globals(BaseModel):
|
|
81
81
|
ICON_BUTTON_CLASS: str = space_join(
|
82
82
|
"bg-white",
|
83
83
|
"p-1",
|
84
|
-
"rounded-
|
84
|
+
"rounded-xs",
|
85
85
|
"text-primary-600",
|
86
86
|
"border",
|
87
87
|
"border-primary-600",
|
88
88
|
"hover:bg-primary-200",
|
89
|
-
"focus:outline-
|
89
|
+
"focus:outline-hidden",
|
90
90
|
"focus:ring-4",
|
91
91
|
"focus:ring-primary-500",
|
92
92
|
"dark:bg-primary-900",
|
@@ -112,7 +112,7 @@ class Globals(BaseModel):
|
|
112
112
|
"bg-neutral-100",
|
113
113
|
"border-neutral-300",
|
114
114
|
"h-4",
|
115
|
-
"rounded",
|
115
|
+
"rounded-sm",
|
116
116
|
"text-primary-600",
|
117
117
|
"w-4",
|
118
118
|
"dark:bg-neutral-700",
|
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},
|
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():
|
fastlife/testing/testclient.py
CHANGED
@@ -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,15 +1,16 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastlifeweb
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.25.0
|
4
4
|
Summary: High-level web framework
|
5
5
|
Author-Email: Guillaume Gauvrit <guillaume@gauvr.it>
|
6
|
-
License: MIT
|
6
|
+
License: MIT
|
7
7
|
Classifier: Development Status :: 4 - Beta
|
8
8
|
Classifier: Framework :: AsyncIO
|
9
9
|
Classifier: Intended Audience :: Developers
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
11
11
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
12
12
|
Classifier: Topic :: Internet :: WWW/HTTP
|
13
|
+
Classifier: Typing :: Typed
|
13
14
|
Project-URL: Homepage, https://mardiros.github.io/fastlife
|
14
15
|
Project-URL: Documentation, https://mardiros.github.io/fastlife
|
15
16
|
Project-URL: Repository, https://github.com/mardiros/fastlife.git
|
@@ -1,4 +1,4 @@
|
|
1
|
-
CHANGELOG.md,sha256=
|
1
|
+
CHANGELOG.md,sha256=vPPDKoWZ3BBiM8Bx1tJV0PpKvuqDWhpLowTYC87ZajA,8019
|
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=
|
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=
|
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=
|
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=
|
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
|
@@ -1721,17 +1721,16 @@ fastlife/settings.py,sha256=q-rz4CEF2RQGow5-m-yZJOvdh3PPb2c1Q_ZLJGnu4VQ,3647
|
|
1721
1721
|
fastlife/shared_utils/__init__.py,sha256=i66ytuf-Ezo7jSiNQHIsBMVIcB-tDX0tg28-pUOlhzE,26
|
1722
1722
|
fastlife/shared_utils/infer.py,sha256=0GflLkaWJ-4LZ1Ig3moR-_o55wwJ_p_vJ4xo-yi3lyA,1406
|
1723
1723
|
fastlife/shared_utils/resolver.py,sha256=Wb9cO2MWavpti63hju15xmwFMgaD5DsQaxikRpB39E8,3713
|
1724
|
-
fastlife/template_globals.py,sha256=
|
1724
|
+
fastlife/template_globals.py,sha256=ZJkO53mFL3l46YrH8ZHLw4hAG1oQcZ3KiBo4friGq2c,8395
|
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=
|
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=
|
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.
|
1733
|
-
fastlifeweb-0.
|
1734
|
-
fastlifeweb-0.
|
1735
|
-
fastlifeweb-0.
|
1736
|
-
|
1737
|
-
fastlifeweb-0.23.1.dist-info/RECORD,,
|
1732
|
+
fastlifeweb-0.25.0.dist-info/METADATA,sha256=yQOfNm_DF3WTxoL0mgqY3PIx3bvnk3x1TVWux8HvNEg,3683
|
1733
|
+
fastlifeweb-0.25.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
1734
|
+
fastlifeweb-0.25.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
1735
|
+
fastlifeweb-0.25.0.dist-info/licenses/LICENSE,sha256=JFWuiKYRXKKMEAsX0aZp3hBcju-HYflJ2rwJAGwbCJo,1080
|
1736
|
+
fastlifeweb-0.25.0.dist-info/RECORD,,
|
tailwind.config.js
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
/** @type {import('tailwindcss').Config} */
|
2
|
-
module.exports = {
|
3
|
-
darkMode: "class",
|
4
|
-
content: [
|
5
|
-
"./src/fastlife/template_globals.py",
|
6
|
-
"./src/fastlife/components/*.jinja",
|
7
|
-
"./src/fastlife/components/**/*.jinja",
|
8
|
-
"./tests/fastlife_app/templates/*.jinja",
|
9
|
-
"./tests/fastlife_app/templates/**/*.jinja",
|
10
|
-
],
|
11
|
-
theme: {
|
12
|
-
extend: {
|
13
|
-
colors: {
|
14
|
-
primary: {
|
15
|
-
50: "#f0f9ff",
|
16
|
-
100: "#e0f2fe",
|
17
|
-
200: "#bae6fd",
|
18
|
-
300: "#7dd3fc",
|
19
|
-
400: "#38bdf8",
|
20
|
-
500: "#0ea5e9",
|
21
|
-
600: "#0284c7",
|
22
|
-
700: "#0369a1",
|
23
|
-
800: "#075985",
|
24
|
-
900: "#0c4a6e",
|
25
|
-
950: "#082f49",
|
26
|
-
},
|
27
|
-
danger: {
|
28
|
-
50: "#fef2f2",
|
29
|
-
100: "#fee2e2",
|
30
|
-
200: "#fecaca",
|
31
|
-
300: "#fca5a5",
|
32
|
-
400: "#f87171",
|
33
|
-
500: "#ef4444",
|
34
|
-
600: "#dc2626",
|
35
|
-
700: "#b91c1c",
|
36
|
-
800: "#991b1b",
|
37
|
-
900: "#7f1d1d",
|
38
|
-
950: "#450a0a",
|
39
|
-
},
|
40
|
-
neutral: {
|
41
|
-
50: "#fafaf9",
|
42
|
-
100: "#f5f5f4",
|
43
|
-
200: "#e7e5e4",
|
44
|
-
300: "#d6d3d1",
|
45
|
-
400: "#a8a29e",
|
46
|
-
500: "#78716c",
|
47
|
-
600: "#57534e",
|
48
|
-
700: "#44403c",
|
49
|
-
800: "#292524",
|
50
|
-
900: "#1c1917",
|
51
|
-
950: "#0c0a09",
|
52
|
-
},
|
53
|
-
},
|
54
|
-
},
|
55
|
-
},
|
56
|
-
plugins: [],
|
57
|
-
};
|
File without changes
|
File without changes
|