fastlifeweb 0.10.0__py3-none-any.whl → 0.11.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.
- fastlife/__init__.py +2 -2
- fastlife/config/__init__.py +13 -0
- fastlife/{configurator → config}/configurator.py +62 -39
- fastlife/{configurator → config}/registry.py +2 -10
- fastlife/{configurator → config}/settings.py +7 -3
- fastlife/middlewares/__init__.py +7 -0
- fastlife/middlewares/base.py +24 -0
- fastlife/middlewares/reverse_proxy/__init__.py +16 -0
- fastlife/middlewares/reverse_proxy/x_forwarded.py +1 -14
- fastlife/middlewares/session/__init__.py +16 -0
- fastlife/middlewares/session/middleware.py +6 -1
- fastlife/middlewares/session/serializer.py +21 -0
- fastlife/request/__init__.py +5 -0
- fastlife/request/form.py +3 -1
- fastlife/request/form_data.py +28 -3
- fastlife/request/request.py +18 -0
- fastlife/routing/__init__.py +7 -0
- fastlife/routing/route.py +45 -0
- fastlife/routing/router.py +12 -4
- fastlife/security/__init__.py +1 -0
- fastlife/security/csrf.py +29 -11
- fastlife/security/policy.py +6 -2
- fastlife/shared_utils/__init__.py +1 -0
- fastlife/shared_utils/infer.py +7 -0
- fastlife/shared_utils/resolver.py +10 -2
- fastlife/templates/A.jinja +33 -9
- fastlife/templates/Button.jinja +55 -32
- fastlife/templates/Checkbox.jinja +20 -6
- fastlife/templates/CsrfToken.jinja +4 -0
- fastlife/templates/Details.jinja +31 -3
- fastlife/templates/Form.jinja +45 -8
- fastlife/templates/H1.jinja +14 -1
- fastlife/templates/H2.jinja +14 -1
- fastlife/templates/H3.jinja +14 -1
- fastlife/templates/H4.jinja +14 -1
- fastlife/templates/H5.jinja +14 -1
- fastlife/templates/H6.jinja +14 -1
- fastlife/templates/Hidden.jinja +3 -3
- fastlife/templates/Input.jinja +21 -8
- fastlife/templates/Label.jinja +18 -2
- fastlife/templates/Option.jinja +14 -2
- fastlife/templates/P.jinja +14 -2
- fastlife/templates/Radio.jinja +34 -12
- fastlife/templates/Select.jinja +15 -4
- fastlife/templates/Summary.jinja +13 -2
- fastlife/templates/Table.jinja +12 -1
- fastlife/templates/Tbody.jinja +11 -1
- fastlife/templates/Td.jinja +12 -1
- fastlife/templates/Textarea.jinja +15 -8
- fastlife/templates/Tfoot.jinja +11 -1
- fastlife/templates/Th.jinja +12 -1
- fastlife/templates/Thead.jinja +11 -1
- fastlife/templates/Tr.jinja +11 -1
- fastlife/templates/pydantic_form/Boolean.jinja +3 -2
- fastlife/templates/pydantic_form/Checklist.jinja +3 -5
- fastlife/templates/pydantic_form/Dropdown.jinja +3 -2
- fastlife/templates/pydantic_form/Error.jinja +4 -3
- fastlife/templates/pydantic_form/Hidden.jinja +2 -1
- fastlife/templates/pydantic_form/Hint.jinja +2 -1
- fastlife/templates/pydantic_form/Model.jinja +9 -2
- fastlife/templates/pydantic_form/Sequence.jinja +10 -2
- fastlife/templates/pydantic_form/Text.jinja +2 -2
- fastlife/templates/pydantic_form/Textarea.jinja +24 -2
- fastlife/templates/pydantic_form/Union.jinja +7 -1
- fastlife/templates/pydantic_form/Widget.jinja +5 -2
- fastlife/templating/binding.py +18 -4
- fastlife/templating/renderer/__init__.py +3 -1
- fastlife/templating/renderer/abstract.py +19 -6
- fastlife/templating/renderer/constants.py +82 -0
- fastlife/templating/renderer/jinjax.py +267 -4
- fastlife/templating/renderer/widgets/base.py +40 -8
- fastlife/templating/renderer/widgets/boolean.py +17 -0
- fastlife/templating/renderer/widgets/checklist.py +19 -0
- fastlife/templating/renderer/widgets/dropdown.py +18 -0
- fastlife/templating/renderer/widgets/factory.py +23 -13
- fastlife/templating/renderer/widgets/hidden.py +14 -0
- fastlife/templating/renderer/widgets/model.py +1 -1
- fastlife/templating/renderer/widgets/sequence.py +1 -1
- fastlife/templating/renderer/widgets/text.py +50 -4
- fastlife/templating/renderer/widgets/union.py +21 -2
- fastlife/testing/testclient.py +3 -3
- fastlife/views/pydantic_form.py +2 -2
- {fastlifeweb-0.10.0.dist-info → fastlifeweb-0.11.0.dist-info}/METADATA +4 -9
- {fastlifeweb-0.10.0.dist-info → fastlifeweb-0.11.0.dist-info}/RECORD +86 -86
- fastlife/configurator/__init__.py +0 -4
- fastlife/configurator/base.py +0 -9
- fastlife/configurator/route_handler.py +0 -29
- fastlife/templates/__init__.py +0 -0
- {fastlifeweb-0.10.0.dist-info → fastlifeweb-0.11.0.dist-info}/LICENSE +0 -0
- {fastlifeweb-0.10.0.dist-info → fastlifeweb-0.11.0.dist-info}/WHEEL +0 -0
@@ -1,9 +1,27 @@
|
|
1
|
+
"""
|
2
|
+
Widget for field of type Enum or Literal.
|
3
|
+
"""
|
4
|
+
|
1
5
|
from typing import Optional, Sequence, Tuple
|
2
6
|
|
3
7
|
from .base import Widget
|
4
8
|
|
5
9
|
|
6
10
|
class DropDownWidget(Widget[str]):
|
11
|
+
"""
|
12
|
+
Widget for field of type Enum or Literal.
|
13
|
+
|
14
|
+
:param name: field name.
|
15
|
+
:param title: title for the widget.
|
16
|
+
:param hint: hint for human.
|
17
|
+
:param aria_label: html input aria-label value.
|
18
|
+
:param value: current value.
|
19
|
+
:param error: error of the value if any.
|
20
|
+
:param options: List of possible values.
|
21
|
+
:param removable: display a button to remove the widget for optional fields.
|
22
|
+
:param token: token used to get unique id on the form.
|
23
|
+
"""
|
24
|
+
|
7
25
|
def __init__(
|
8
26
|
self,
|
9
27
|
name: str,
|
@@ -1,10 +1,14 @@
|
|
1
|
+
"""
|
2
|
+
Transform.
|
3
|
+
"""
|
4
|
+
|
1
5
|
import secrets
|
2
6
|
from collections.abc import MutableSequence, Sequence
|
3
7
|
from decimal import Decimal
|
4
8
|
from enum import Enum
|
5
9
|
from inspect import isclass
|
6
10
|
from types import NoneType
|
7
|
-
from typing import Any, Literal, Mapping,
|
11
|
+
from typing import Any, Literal, Mapping, Type, cast, get_origin
|
8
12
|
from uuid import UUID
|
9
13
|
|
10
14
|
from markupsafe import Markup
|
@@ -14,20 +18,26 @@ from pydantic.fields import FieldInfo
|
|
14
18
|
from fastlife.request.form import FormModel
|
15
19
|
from fastlife.shared_utils.infer import is_complex_type, is_union
|
16
20
|
from fastlife.templating.renderer.abstract import AbstractTemplateRenderer
|
21
|
+
from fastlife.templating.renderer.widgets.base import Widget
|
17
22
|
from fastlife.templating.renderer.widgets.boolean import BooleanWidget
|
18
23
|
from fastlife.templating.renderer.widgets.checklist import Checkable, ChecklistWidget
|
19
24
|
from fastlife.templating.renderer.widgets.dropdown import DropDownWidget
|
20
25
|
from fastlife.templating.renderer.widgets.hidden import HiddenWidget
|
26
|
+
from fastlife.templating.renderer.widgets.model import ModelWidget
|
21
27
|
from fastlife.templating.renderer.widgets.sequence import SequenceWidget
|
22
|
-
|
23
|
-
from .
|
24
|
-
from .model import ModelWidget
|
25
|
-
from .text import TextWidget
|
26
|
-
from .union import UnionWidget
|
28
|
+
from fastlife.templating.renderer.widgets.text import TextWidget
|
29
|
+
from fastlife.templating.renderer.widgets.union import UnionWidget
|
27
30
|
|
28
31
|
|
29
32
|
class WidgetFactory:
|
30
|
-
|
33
|
+
"""
|
34
|
+
Form builder for pydantic model.
|
35
|
+
|
36
|
+
:param renderer: template engine to render widget.
|
37
|
+
:param token: reuse a token.
|
38
|
+
"""
|
39
|
+
|
40
|
+
def __init__(self, renderer: AbstractTemplateRenderer, token: str | None = None):
|
31
41
|
self.renderer = renderer
|
32
42
|
self.token = token or secrets.token_urlsafe(4).replace("_", "-")
|
33
43
|
|
@@ -153,7 +163,7 @@ class WidgetFactory:
|
|
153
163
|
self,
|
154
164
|
field_name: str,
|
155
165
|
typ: Type[BaseModel],
|
156
|
-
field:
|
166
|
+
field: FieldInfo | None,
|
157
167
|
value: Mapping[str, Any],
|
158
168
|
form_errors: Mapping[str, Any],
|
159
169
|
removable: bool,
|
@@ -195,7 +205,7 @@ class WidgetFactory:
|
|
195
205
|
self,
|
196
206
|
field_name: str,
|
197
207
|
field_type: Type[Any],
|
198
|
-
field:
|
208
|
+
field: FieldInfo | None,
|
199
209
|
value: Any,
|
200
210
|
form_errors: Mapping[str, Any],
|
201
211
|
removable: bool,
|
@@ -262,8 +272,8 @@ class WidgetFactory:
|
|
262
272
|
self,
|
263
273
|
field_name: str,
|
264
274
|
field_type: Type[Any],
|
265
|
-
field:
|
266
|
-
value:
|
275
|
+
field: FieldInfo | None,
|
276
|
+
value: Sequence[Any] | None,
|
267
277
|
form_errors: Mapping[str, Any],
|
268
278
|
removable: bool,
|
269
279
|
) -> Widget[Any]:
|
@@ -300,8 +310,8 @@ class WidgetFactory:
|
|
300
310
|
self,
|
301
311
|
field_name: str,
|
302
312
|
field_type: Type[Any],
|
303
|
-
field:
|
304
|
-
value:
|
313
|
+
field: FieldInfo | None,
|
314
|
+
value: Sequence[Any] | None,
|
305
315
|
form_errors: Mapping[str, Any],
|
306
316
|
removable: bool,
|
307
317
|
) -> Widget[Any]:
|
@@ -1,8 +1,22 @@
|
|
1
1
|
from typing import Any
|
2
|
+
|
2
3
|
from .base import Widget
|
3
4
|
|
4
5
|
|
5
6
|
class HiddenWidget(Widget[str]):
|
7
|
+
'''
|
8
|
+
Widget to annotate to display a field as an hidden field.
|
9
|
+
|
10
|
+
::
|
11
|
+
from pydantic import BaseModel
|
12
|
+
from fastlife.templating.renderer.widgets.hidden import HiddenWidget
|
13
|
+
|
14
|
+
class MyForm(BaseModel):
|
15
|
+
id: Annotated[str, HiddenWidget] = Field(...)
|
16
|
+
"""Identifier in the database."""
|
17
|
+
|
18
|
+
'''
|
19
|
+
|
6
20
|
def __init__(
|
7
21
|
self,
|
8
22
|
name: str,
|
@@ -37,7 +37,7 @@ class ModelWidget(Widget[Sequence[Widget[Any]]]):
|
|
37
37
|
return "pydantic_form.Model"
|
38
38
|
|
39
39
|
def to_html(self, renderer: AbstractTemplateRenderer) -> Markup:
|
40
|
-
"""Return the html version"""
|
40
|
+
"""Return the html version."""
|
41
41
|
children_widget = [child.to_html(renderer) for child in self.value or []]
|
42
42
|
kwargs = {
|
43
43
|
"widget": self,
|
@@ -40,7 +40,7 @@ class SequenceWidget(Widget[Sequence[Widget[Any]]]):
|
|
40
40
|
return TypeWrapper(self.item_type, route_prefix, self.name, self.token)
|
41
41
|
|
42
42
|
def to_html(self, renderer: "AbstractTemplateRenderer") -> Markup:
|
43
|
-
"""Return the html version"""
|
43
|
+
"""Return the html version."""
|
44
44
|
children = [Markup(item.to_html(renderer)) for item in self.value or []]
|
45
45
|
return Markup(
|
46
46
|
renderer.render_template(
|
@@ -4,6 +4,20 @@ from .base import Widget
|
|
4
4
|
|
5
5
|
|
6
6
|
class TextWidget(Widget[str]):
|
7
|
+
"""
|
8
|
+
Widget for text like field (email, ...).
|
9
|
+
|
10
|
+
:param name: input name.
|
11
|
+
:param title: title for the widget.
|
12
|
+
:param hint: hint for human.
|
13
|
+
:param aria_label: html input aria-label value.
|
14
|
+
:param placeholder: html input placeholder value.
|
15
|
+
:param error: error of the value if any.
|
16
|
+
:param value: current value.
|
17
|
+
:param removable: display a button to remove the widget for optional fields.
|
18
|
+
:param token: token used to get unique id on the form.
|
19
|
+
"""
|
20
|
+
|
7
21
|
def __init__(
|
8
22
|
self,
|
9
23
|
name: str,
|
@@ -13,10 +27,10 @@ class TextWidget(Widget[str]):
|
|
13
27
|
aria_label: Optional[str] = None,
|
14
28
|
placeholder: Optional[str] = None,
|
15
29
|
error: str | None = None,
|
16
|
-
removable: bool = False,
|
17
30
|
value: str = "",
|
18
|
-
token: Optional[str] = None,
|
19
31
|
input_type: str = "text",
|
32
|
+
removable: bool = False,
|
33
|
+
token: str,
|
20
34
|
) -> None:
|
21
35
|
super().__init__(
|
22
36
|
name,
|
@@ -36,6 +50,38 @@ class TextWidget(Widget[str]):
|
|
36
50
|
|
37
51
|
|
38
52
|
class TextareaWidget(Widget[str]):
|
53
|
+
"""
|
54
|
+
Render a Textearea for a string or event a sequence of string.
|
55
|
+
|
56
|
+
```
|
57
|
+
from fastlife.templating.renderer.widgets.text import TextareaWidget
|
58
|
+
from pydantic import BaseModel, Field, field_validator
|
59
|
+
|
60
|
+
class TaggedParagraphForm(BaseModel):
|
61
|
+
paragraph: Annotated[str, TextareaWidget] = Field(...)
|
62
|
+
tags: Annotated[Sequence[str], TextareaWidget] = Field(
|
63
|
+
default_factory=list,
|
64
|
+
title="Tags",
|
65
|
+
description="One tag per line",
|
66
|
+
)
|
67
|
+
|
68
|
+
@field_validator("tags", mode="before")
|
69
|
+
def split(cls, s: Any) -> Sequence[str]:
|
70
|
+
return s.split() if s else []
|
71
|
+
```
|
72
|
+
|
73
|
+
:param name: input name.
|
74
|
+
:param title: title for the widget.
|
75
|
+
:param hint: hint for human.
|
76
|
+
:param aria_label: html input aria-label value.
|
77
|
+
:param placeholder: html input placeholder value.
|
78
|
+
:param error: error of the value if any.
|
79
|
+
:param value: current value.
|
80
|
+
:param removable: display a button to remove the widget for optional fields.
|
81
|
+
:param token: token used to get unique id on the form.
|
82
|
+
|
83
|
+
"""
|
84
|
+
|
39
85
|
def __init__(
|
40
86
|
self,
|
41
87
|
name: str,
|
@@ -45,9 +91,9 @@ class TextareaWidget(Widget[str]):
|
|
45
91
|
aria_label: Optional[str] = None,
|
46
92
|
placeholder: Optional[str] = None,
|
47
93
|
error: str | None = None,
|
48
|
-
removable: bool = False,
|
49
94
|
value: str = "",
|
50
|
-
|
95
|
+
removable: bool = False,
|
96
|
+
token: str,
|
51
97
|
) -> None:
|
52
98
|
super().__init__(
|
53
99
|
name,
|
@@ -1,3 +1,6 @@
|
|
1
|
+
"""
|
2
|
+
Widget for field of type Union.
|
3
|
+
"""
|
1
4
|
from typing import Any, Optional, Sequence, Type, Union
|
2
5
|
|
3
6
|
from markupsafe import Markup
|
@@ -9,6 +12,21 @@ from .base import TypeWrapper, Widget
|
|
9
12
|
|
10
13
|
|
11
14
|
class UnionWidget(Widget[Widget[Any]]):
|
15
|
+
"""
|
16
|
+
Widget for union types.
|
17
|
+
|
18
|
+
:param name: input name.
|
19
|
+
:param title: title for the widget.
|
20
|
+
:param hint: hint for human.
|
21
|
+
:param aria_label: html input aria-label value.
|
22
|
+
:param value: current value.
|
23
|
+
:param error: error of the value if any.
|
24
|
+
:param children_types: childrens types list.
|
25
|
+
:param removable: display a button to remove the widget for optional fields.
|
26
|
+
:param token: token used to get unique id on the form.
|
27
|
+
|
28
|
+
"""
|
29
|
+
|
12
30
|
def __init__(
|
13
31
|
self,
|
14
32
|
name: str,
|
@@ -19,8 +37,8 @@ class UnionWidget(Widget[Widget[Any]]):
|
|
19
37
|
value: Optional[Widget[Any]],
|
20
38
|
error: str | None = None,
|
21
39
|
children_types: Sequence[Type[BaseModel]],
|
40
|
+
removable: bool = False,
|
22
41
|
token: str,
|
23
|
-
removable: bool,
|
24
42
|
):
|
25
43
|
super().__init__(
|
26
44
|
name,
|
@@ -36,6 +54,7 @@ class UnionWidget(Widget[Widget[Any]]):
|
|
36
54
|
self.parent_name = name
|
37
55
|
|
38
56
|
def build_types(self, route_prefix: str) -> Sequence[TypeWrapper]:
|
57
|
+
"""Wrap types in the union in order to get the in their own widgets."""
|
39
58
|
return [
|
40
59
|
TypeWrapper(typ, route_prefix, self.name, self.token)
|
41
60
|
for typ in self.children_types
|
@@ -45,7 +64,7 @@ class UnionWidget(Widget[Widget[Any]]):
|
|
45
64
|
return "pydantic_form.Union"
|
46
65
|
|
47
66
|
def to_html(self, renderer: "AbstractTemplateRenderer") -> Markup:
|
48
|
-
"""Return the html version"""
|
67
|
+
"""Return the html version."""
|
49
68
|
child = Markup(self.value.to_html(renderer)) if self.value else ""
|
50
69
|
return Markup(
|
51
70
|
renderer.render_template(
|
fastlife/testing/testclient.py
CHANGED
@@ -13,7 +13,7 @@ from fastapi.testclient import TestClient
|
|
13
13
|
from multidict import MultiDict
|
14
14
|
from starlette.types import ASGIApp
|
15
15
|
|
16
|
-
from fastlife.
|
16
|
+
from fastlife.config.settings import Settings
|
17
17
|
from fastlife.middlewares.session.serializer import AbsractSessionSerializer
|
18
18
|
from fastlife.shared_utils.resolver import resolve
|
19
19
|
|
@@ -153,7 +153,7 @@ class Element:
|
|
153
153
|
|
154
154
|
class WebForm:
|
155
155
|
"""
|
156
|
-
Handle form.
|
156
|
+
Handle html form.
|
157
157
|
|
158
158
|
Form are filled out and submit with methods and try to avoid invalid
|
159
159
|
usage, such as selecting an option that don't exists is not possible here.
|
@@ -504,7 +504,7 @@ class WebTestClient:
|
|
504
504
|
|
505
505
|
@property
|
506
506
|
def cookies(self) -> Cookies:
|
507
|
-
"""HTTP Cookies"""
|
507
|
+
"""HTTP Cookies."""
|
508
508
|
return self.testclient.cookies
|
509
509
|
|
510
510
|
@property
|
fastlife/views/pydantic_form.py
CHANGED
@@ -4,7 +4,7 @@ from fastapi import Query, Request, Response
|
|
4
4
|
from pydantic.fields import FieldInfo
|
5
5
|
|
6
6
|
from fastlife import Configurator, configure
|
7
|
-
from fastlife.
|
7
|
+
from fastlife.config.registry import Registry
|
8
8
|
from fastlife.shared_utils.resolver import resolve_extended
|
9
9
|
|
10
10
|
|
@@ -25,7 +25,7 @@ async def show_widget(
|
|
25
25
|
if title:
|
26
26
|
field = FieldInfo(title=title)
|
27
27
|
data = reg.renderer(request).pydantic_form_field(
|
28
|
-
model=model_cls,
|
28
|
+
model=model_cls, # type: ignore
|
29
29
|
name=name,
|
30
30
|
token=token,
|
31
31
|
removable=removable,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fastlifeweb
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.11.0
|
4
4
|
Summary: High-level web framework
|
5
5
|
Home-page: https://github.com/mardiros/fastlife
|
6
6
|
License: BSD-derived
|
@@ -18,7 +18,6 @@ Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Classifier: Topic :: Internet :: WWW/HTTP
|
19
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
20
20
|
Requires-Dist: beautifulsoup4[testing] (>=4.12.2,<5.0.0)
|
21
|
-
Requires-Dist: behave (>=1.2.6,<2.0.0)
|
22
21
|
Requires-Dist: fastapi (>=0.112.0,<0.113.0)
|
23
22
|
Requires-Dist: itsdangerous (>=2.1.2,<3.0.0)
|
24
23
|
Requires-Dist: jinjax (>=0.44,<0.45)
|
@@ -33,20 +32,16 @@ Description-Content-Type: text/markdown
|
|
33
32
|
|
34
33
|
# Fastlife
|
35
34
|
|
36
|
-
[](https://mardiros.github.io/fastlife/)
|
36
|
+
[](https://github.com/mardiros/fastlife/actions/workflows/main.yml)
|
37
|
+
[](https://codecov.io/gh/mardiros/fastlife)
|
40
38
|
|
41
39
|
A high-level Python web framework based on FastAPI, JinjaX, Pydandic and htmx.
|
42
40
|
|
43
41
|
The intention is to prototype web application fast. It generate forms directly from
|
44
42
|
Pydantic models.
|
45
43
|
|
46
|
-
|
47
|
-
|
48
44
|
Under heavy development.
|
49
45
|
|
50
|
-
|
51
46
|
The package is available on pypi with the name fastlifeweb.
|
52
47
|
|
@@ -1,57 +1,57 @@
|
|
1
|
-
fastlife/__init__.py,sha256=
|
2
|
-
fastlife/
|
3
|
-
fastlife/configurator
|
4
|
-
fastlife/
|
5
|
-
fastlife/
|
6
|
-
fastlife/
|
7
|
-
fastlife/
|
8
|
-
fastlife/middlewares/__init__.py,sha256=
|
9
|
-
fastlife/middlewares/reverse_proxy/
|
10
|
-
fastlife/middlewares/
|
11
|
-
fastlife/middlewares/session/
|
12
|
-
fastlife/middlewares/session/
|
13
|
-
fastlife/middlewares/session/serializer.py,sha256=qpVnHQjYTxw3aOnoEOKIjOFJg2z45KjiX5sipWk2gws,1458
|
1
|
+
fastlife/__init__.py,sha256=4tACh9tKuAaMZ-qK0GWJN-WLqaou8H7ZPE9sXfs_NlI,303
|
2
|
+
fastlife/config/__init__.py,sha256=3AoTQ5ojTCYDU3i1vDUCDC5pbBOeSWZ0w1Xo6A1qDrY,284
|
3
|
+
fastlife/config/configurator.py,sha256=ol8tdOSDk9Q_M1Nkme-3DaAEXkV5j6XXYIFR3V0Xxvw,8640
|
4
|
+
fastlife/config/registry.py,sha256=v1IKPWKyPaG4TbCzrkC4uU51vRoSdpLWXEvAh_mbtjE,1246
|
5
|
+
fastlife/config/settings.py,sha256=mdM1YlBXFq2HDWCKeMkBeHmW4NlgKEPZyKAxumUsrbo,3760
|
6
|
+
fastlife/middlewares/__init__.py,sha256=C3DUOzR5EhlAv5Zq7h-Abyvkd7bUsJohTRSB2wpRYQE,220
|
7
|
+
fastlife/middlewares/base.py,sha256=9OYqByRuVoIrLt353NOedPQTLdr7LSmxhb2BZcp20qk,638
|
8
|
+
fastlife/middlewares/reverse_proxy/__init__.py,sha256=XTG9_Djw92wlyYh1dUDq8kkO8Oq61kBMqd_jNCsLfaQ,845
|
9
|
+
fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=WC4xV3i6_Ogqsf_Zgt1ESml8zfnPbJJJkPlC2gTEqW8,1095
|
10
|
+
fastlife/middlewares/session/__init__.py,sha256=3XgXcIO6yQls5G7x8K2T8b7a_enA_7rQptWZcp3j2Ak,1400
|
11
|
+
fastlife/middlewares/session/middleware.py,sha256=AlRIFXfn3JesKJzMAFUHDOo22mfuwDHkyecDHo9jCdA,3172
|
12
|
+
fastlife/middlewares/session/serializer.py,sha256=fTdZCop0y4VkCMyOIo6GEbo5fVWrwsBXaSWfConPL8E,2144
|
14
13
|
fastlife/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
fastlife/request/__init__.py,sha256=
|
16
|
-
fastlife/request/form.py,sha256=
|
17
|
-
fastlife/request/form_data.py,sha256=
|
18
|
-
fastlife/
|
19
|
-
fastlife/routing/
|
20
|
-
fastlife/
|
21
|
-
fastlife/
|
22
|
-
fastlife/security/
|
23
|
-
fastlife/
|
24
|
-
fastlife/
|
25
|
-
fastlife/shared_utils/
|
26
|
-
fastlife/
|
27
|
-
fastlife/
|
28
|
-
fastlife/templates/
|
29
|
-
fastlife/templates/
|
30
|
-
fastlife/templates/
|
31
|
-
fastlife/templates/
|
32
|
-
fastlife/templates/
|
33
|
-
fastlife/templates/
|
34
|
-
fastlife/templates/
|
35
|
-
fastlife/templates/
|
36
|
-
fastlife/templates/
|
37
|
-
fastlife/templates/
|
38
|
-
fastlife/templates/
|
39
|
-
fastlife/templates/
|
40
|
-
fastlife/templates/
|
41
|
-
fastlife/templates/
|
42
|
-
fastlife/templates/
|
43
|
-
fastlife/templates/
|
44
|
-
fastlife/templates/
|
45
|
-
fastlife/templates/
|
46
|
-
fastlife/templates/
|
47
|
-
fastlife/templates/
|
48
|
-
fastlife/templates/
|
49
|
-
fastlife/templates/
|
50
|
-
fastlife/templates/
|
51
|
-
fastlife/templates/
|
52
|
-
fastlife/templates/
|
53
|
-
fastlife/templates/
|
54
|
-
fastlife/templates/
|
14
|
+
fastlife/request/__init__.py,sha256=C5lZAsUZJDw0TfTegRyN5BEhzgfiqvfc8YXu2vp0siU,73
|
15
|
+
fastlife/request/form.py,sha256=FucGua79LCKqNBP6Ycle7-5JU6EMI6SrHCgoJBcvGY4,3532
|
16
|
+
fastlife/request/form_data.py,sha256=BLAanhP0u-9VXNmHyjVTj4fbGFWNEyJJwpHTw_mqVmw,4459
|
17
|
+
fastlife/request/request.py,sha256=NGeU6Wpdh-lnbmgZyjCo31fre1Nl86M8yZqvNsOTsZA,544
|
18
|
+
fastlife/routing/__init__.py,sha256=8EMnQE5n8oA4J9_c3nxzwKDVt3tefZ6fGH0d2owE8mo,195
|
19
|
+
fastlife/routing/route.py,sha256=GehIHNnqZANXipdn1_dWzZnZlByc2Q4Yh39MuczS3Sc,1405
|
20
|
+
fastlife/routing/router.py,sha256=zoQ9Gmo6dEm-IIf2etIQrvhrXP0i3RWkVZuJZ8HMno4,481
|
21
|
+
fastlife/security/__init__.py,sha256=QYDcJ3oXQzqXQxoDD_6biGAtercFrtePttoifiL1j34,25
|
22
|
+
fastlife/security/csrf.py,sha256=Y1M37tFe5dsnbA_aklcFZrLm6ePzEpKLsQsmojDk3Dc,2141
|
23
|
+
fastlife/security/policy.py,sha256=k33DVbub0_QvKCgD9vo_cdyNRUS2e7x7wctarVj8Dko,945
|
24
|
+
fastlife/shared_utils/__init__.py,sha256=i66ytuf-Ezo7jSiNQHIsBMVIcB-tDX0tg28-pUOlhzE,26
|
25
|
+
fastlife/shared_utils/infer.py,sha256=CJjsL_F5OQRG7-0_89MQiZhyd7IcMGyirlQhjtcaIT4,728
|
26
|
+
fastlife/shared_utils/resolver.py,sha256=BRU88Ej4oA1iDIyG4Z6T7Q9WFvPHiMm6zuSh623312A,1725
|
27
|
+
fastlife/templates/A.jinja,sha256=Yji2aeqtQqkFqXhVQJZaVN60pX_418WGM2XdbIzZEwI,1399
|
28
|
+
fastlife/templates/Button.jinja,sha256=8qqMIOI8EBerNCiq12O7whv0D5pOhGadJvMe8mp8l5Q,2320
|
29
|
+
fastlife/templates/Checkbox.jinja,sha256=A4Cw3MvI_7gy_FdCQpjQmN5qIjSCcaPYkGhP1xY31cA,763
|
30
|
+
fastlife/templates/CsrfToken.jinja,sha256=ftqhcMibf1G8pbGCytlUcj5LGEmD8QJKwVKTro5w-ns,199
|
31
|
+
fastlife/templates/Details.jinja,sha256=LzXncOoytRoeJ5rKl19V057eEwPWN9LT4Ag63GjCxE0,751
|
32
|
+
fastlife/templates/Form.jinja,sha256=tIHzua02cXX-vgGvRd6_zQetZJjPMGsJ6KZFgNEq11I,1530
|
33
|
+
fastlife/templates/H1.jinja,sha256=W-lnoGHLIbJToKXHtD__HSfCqMycafB9l2uW_Uf976E,385
|
34
|
+
fastlife/templates/H2.jinja,sha256=QRAn9Nuhws1HZPaRNFN9OvGxbhRfbc2IvU5qu1iyk10,385
|
35
|
+
fastlife/templates/H3.jinja,sha256=wUdplEVscd99lpdPRmMEMIaJ_ND7c4_mNiWuC9q0bf4,385
|
36
|
+
fastlife/templates/H4.jinja,sha256=0i6za9gaWHNkiNVEITOnEoQPQc3-qgOk_uTJ2hJMilk,385
|
37
|
+
fastlife/templates/H5.jinja,sha256=pE50LIDT1cst0-BHMsrm5sXClqZbXgm2n7Q05LDqLkQ,385
|
38
|
+
fastlife/templates/H6.jinja,sha256=BJOS5JGsMKVtiIHnldWlFdO9GqyOGcilPfOiGeBZ-Og,385
|
39
|
+
fastlife/templates/Hidden.jinja,sha256=-D74wZ7qp2n5l_8HKmDhX5v_M2sAJ5l-w_z9m5d5KvA,283
|
40
|
+
fastlife/templates/Input.jinja,sha256=ISCXs-YHeFqS1geIsNf8p32xUje7ccBtXznwOhdXAsM,931
|
41
|
+
fastlife/templates/Label.jinja,sha256=H4AkLUIpkGkO3cq9xjR7fXT7CCo0HMIO_AR3FEGQDng,547
|
42
|
+
fastlife/templates/Option.jinja,sha256=x6t7uUQsI1YSRstD4bSVlgK2wm8NJUXnzOWfNWGlk_Y,448
|
43
|
+
fastlife/templates/P.jinja,sha256=AZax3MlZAyxUbdKWuiaCYk9uDsXqEzv_BaNa25k4RCY,386
|
44
|
+
fastlife/templates/Radio.jinja,sha256=u0x1lUbpSh6P3Y1FxJQ6Ms0MSRddCSme8B2sZdqkRJE,1523
|
45
|
+
fastlife/templates/Select.jinja,sha256=OD8V15-rkUyMwHkqQo9xiiFKxx8KpMRjGgqS0PFOCkY,566
|
46
|
+
fastlife/templates/Summary.jinja,sha256=CbvVg0-R5w-CDEXSWfYzQ-hE0q4wNDsLTDO6H_C7Mj0,863
|
47
|
+
fastlife/templates/Table.jinja,sha256=gKcjoRWn2cNg5DRr-2AQ65YD6mzeF3sMuyOCerGOTRc,400
|
48
|
+
fastlife/templates/Tbody.jinja,sha256=LG6B41wnKc3My3LoCQJPYiLnd7pz3JmRAJ2o7a_m1hs,325
|
49
|
+
fastlife/templates/Td.jinja,sha256=oz69BLz9uAtDZ24Uw6YvoN6P2L84KC8R_Eq4cx5Dnc4,384
|
50
|
+
fastlife/templates/Textarea.jinja,sha256=0WsTi-yxVwYXndmJJN93WblQVqM0h0NCSMUDwoC3kdc,636
|
51
|
+
fastlife/templates/Tfoot.jinja,sha256=hxdYkc-3P27Qm9ZobSxhpjugOFJifVia20uHzTXHvIk,325
|
52
|
+
fastlife/templates/Th.jinja,sha256=XO5IX2BDhUj9JeMEArdMiXsrLcgc0Zj2bZAV_gnFBYQ,385
|
53
|
+
fastlife/templates/Thead.jinja,sha256=FB0ZaYwQR1KEJun5XpuO4sXsUuyPabXxf8M5qkeD-xI,324
|
54
|
+
fastlife/templates/Tr.jinja,sha256=tWMonYy0XPCaGCeheo6aqqSXo7wxqxz6hPUBGAWrHNI,316
|
55
55
|
fastlife/templates/icons/AcademicCap.jinja,sha256=0yJiwNF09SXGmssEHFkEE_2GPb2LFN1BIR4DChDRBls,528
|
56
56
|
fastlife/templates/icons/AdjustmentsHorizontal.jinja,sha256=eaAOfrTqfmkJmNaFeCiBSzSCohu6_kqNSuFIB1Vz1RE,568
|
57
57
|
fastlife/templates/icons/AdjustmentsVertical.jinja,sha256=n7jBi400_q6KnhMABtUwKBBM_7n1IXFtdtaNwamrfxs,560
|
@@ -1664,40 +1664,40 @@ fastlife/templates/icons/solid/Wrench.jinja,sha256=7DafP_B4LT5QkvTeMUx_zmLYliM2e
|
|
1664
1664
|
fastlife/templates/icons/solid/WrenchScrewdriver.jinja,sha256=4R90jRI63aRFxvQQCYs75lDbPYoNO600x4hKPlRku_4,1368
|
1665
1665
|
fastlife/templates/icons/solid/XCircle.jinja,sha256=0VoZ58uL7mLSzYlFUme5chykpQL9h7yJeq29dN6GjZ0,593
|
1666
1666
|
fastlife/templates/icons/solid/XMark.jinja,sha256=tvAtbOfIVteEEzFGSejQlq4Z_rFD3J9zf7EEjCNQA0Q,507
|
1667
|
-
fastlife/templates/pydantic_form/Boolean.jinja,sha256=
|
1668
|
-
fastlife/templates/pydantic_form/Checklist.jinja,sha256=
|
1669
|
-
fastlife/templates/pydantic_form/Dropdown.jinja,sha256=
|
1670
|
-
fastlife/templates/pydantic_form/Error.jinja,sha256=
|
1671
|
-
fastlife/templates/pydantic_form/Hidden.jinja,sha256=
|
1672
|
-
fastlife/templates/pydantic_form/Hint.jinja,sha256=
|
1673
|
-
fastlife/templates/pydantic_form/Model.jinja,sha256
|
1674
|
-
fastlife/templates/pydantic_form/Sequence.jinja,sha256=
|
1675
|
-
fastlife/templates/pydantic_form/Text.jinja,sha256=
|
1676
|
-
fastlife/templates/pydantic_form/Textarea.jinja,sha256=
|
1677
|
-
fastlife/templates/pydantic_form/Union.jinja,sha256
|
1678
|
-
fastlife/templates/pydantic_form/Widget.jinja,sha256=
|
1667
|
+
fastlife/templates/pydantic_form/Boolean.jinja,sha256=jC5YHjgcVskigq4omDFws6r7McBtcA--yOLiv5Yjtt8,593
|
1668
|
+
fastlife/templates/pydantic_form/Checklist.jinja,sha256=d1msOWqtBOY7X7W_gHOpSlIrGR3PNzKDExCIuEejozw,923
|
1669
|
+
fastlife/templates/pydantic_form/Dropdown.jinja,sha256=_qBnj40pmitUhO9cbTXtOrd6XlkJ2pz3GY45bIevMjc,692
|
1670
|
+
fastlife/templates/pydantic_form/Error.jinja,sha256=vVSb1BKyKLOD4IOAM7aCKSNh7aAlmoiZVgRuvDCwLIo,205
|
1671
|
+
fastlife/templates/pydantic_form/Hidden.jinja,sha256=9gAl6NVC9bf_S0EQ1ieswaJz7LPmPX5atlt1BrDNTNo,228
|
1672
|
+
fastlife/templates/pydantic_form/Hint.jinja,sha256=8leBpfMGDmalc_KAjr2paTojr_rwq-luS6m_1BGj7Tw,202
|
1673
|
+
fastlife/templates/pydantic_form/Model.jinja,sha256=-lCcOzfExev3IuNUrbPx176SrBl9lbmGE9dii9fgyO4,925
|
1674
|
+
fastlife/templates/pydantic_form/Sequence.jinja,sha256=uCFqTUfmmRw5gBLiEDb_2OysVhsNOlkvv8fO5HpqrbA,1803
|
1675
|
+
fastlife/templates/pydantic_form/Text.jinja,sha256=MRYNHnmK_WTPPZzRWPRlR9XMgER5jUAYIC5tDmLNXHY,518
|
1676
|
+
fastlife/templates/pydantic_form/Textarea.jinja,sha256=WKj5G7cYrzblWSLd0MvVZd1pEvg_8tIUClibzdx2FOc,1055
|
1677
|
+
fastlife/templates/pydantic_form/Union.jinja,sha256=-FmtWABBNezkiG3yGcmgvWLAETN9NT9LJySwBgEvBLc,1477
|
1678
|
+
fastlife/templates/pydantic_form/Widget.jinja,sha256=kT2SDB5yq5yHEwhL7SG4mmRXCtRPn4Nd3vVuQmqJ9S8,401
|
1679
1679
|
fastlife/templating/__init__.py,sha256=UY_hSTlJKDZnkSIK-BzRD4_AXOWgHbRuvJsKAS9ljgE,307
|
1680
|
-
fastlife/templating/binding.py,sha256=
|
1681
|
-
fastlife/templating/renderer/__init__.py,sha256=
|
1682
|
-
fastlife/templating/renderer/abstract.py,sha256=
|
1683
|
-
fastlife/templating/renderer/constants.py,sha256=
|
1684
|
-
fastlife/templating/renderer/jinjax.py,sha256=
|
1680
|
+
fastlife/templating/binding.py,sha256=Ox4tjmwIykpnU1ZzyAqeLYMunlVQwHVxuNvhuYKh6AA,1920
|
1681
|
+
fastlife/templating/renderer/__init__.py,sha256=10RHpo4S6ehjd-90dFq2mDul8vIK15o-WdMpc-NXdA0,257
|
1682
|
+
fastlife/templating/renderer/abstract.py,sha256=eiTEm7a7f42gfYhTAopMUZMMVVG1fkTZCZ3Sdp49vKA,3971
|
1683
|
+
fastlife/templating/renderer/constants.py,sha256=MGdUjkF9hsPMN8rOS49eWbAApcb8FL-FAeFvJU8k90M,8387
|
1684
|
+
fastlife/templating/renderer/jinjax.py,sha256=2248WYc0lCYCEBmsQqx0VxjJCFVynIBw7KNZ9gcoQOM,12270
|
1685
1685
|
fastlife/templating/renderer/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1686
|
-
fastlife/templating/renderer/widgets/base.py,sha256=
|
1687
|
-
fastlife/templating/renderer/widgets/boolean.py,sha256
|
1688
|
-
fastlife/templating/renderer/widgets/checklist.py,sha256=
|
1689
|
-
fastlife/templating/renderer/widgets/dropdown.py,sha256=
|
1690
|
-
fastlife/templating/renderer/widgets/factory.py,sha256=
|
1691
|
-
fastlife/templating/renderer/widgets/hidden.py,sha256=
|
1692
|
-
fastlife/templating/renderer/widgets/model.py,sha256=
|
1693
|
-
fastlife/templating/renderer/widgets/sequence.py,sha256=
|
1694
|
-
fastlife/templating/renderer/widgets/text.py,sha256=
|
1695
|
-
fastlife/templating/renderer/widgets/union.py,sha256=
|
1686
|
+
fastlife/templating/renderer/widgets/base.py,sha256=Act7A72nKq4paI6dh0A8nL4ywfTii4DYeu7Ky3T5x68,4000
|
1687
|
+
fastlife/templating/renderer/widgets/boolean.py,sha256=tOztwSLrJRD_bqG_m_QmY1yKlBB1oPw5j4I9QHP-J1M,1139
|
1688
|
+
fastlife/templating/renderer/widgets/checklist.py,sha256=Zl0Qu7wFK7nh_ORmjTNalZvnsGNn78rc5EOPmsEtqTc,1649
|
1689
|
+
fastlife/templating/renderer/widgets/dropdown.py,sha256=uel-7CWZGTerl2rD0-M54Nhg7ZWC7YYkWaJ_aPqkC2I,1616
|
1690
|
+
fastlife/templating/renderer/widgets/factory.py,sha256=hteucZEdxPkAU2BPFPXTNNKxSzzE9ZbHL4kUpJmNbP4,17604
|
1691
|
+
fastlife/templating/renderer/widgets/hidden.py,sha256=iEUxB9M9hOz7EPDiIMe5cWmae7cwoq4dSFDpVGgurpI,697
|
1692
|
+
fastlife/templating/renderer/widgets/model.py,sha256=imajTbB5ZxdJAy7UFqhPF3NVA6hZyjNL0Zg60uwkJlM,1276
|
1693
|
+
fastlife/templating/renderer/widgets/sequence.py,sha256=zvQrCvPIJNRVooNX16hM64sXCivclDlVS1MnGH4_Rq8,1516
|
1694
|
+
fastlife/templating/renderer/widgets/text.py,sha256=lyc_aje_Yx0EpiYFbWtOLdLIfU8_5SLor4QvF3RIACY,3177
|
1695
|
+
fastlife/templating/renderer/widgets/union.py,sha256=HN16dZxel5LHaZWnPE1izPohaEDTWxjcbFuoSqOFCO8,2530
|
1696
1696
|
fastlife/testing/__init__.py,sha256=vuqwoNUd3BuIp3fm7nkvmYkIGjIimf5zUGhDkeWrg2s,98
|
1697
|
-
fastlife/testing/testclient.py,sha256=
|
1697
|
+
fastlife/testing/testclient.py,sha256=BC7lLQ_jc59UmknAKzgRtW9a3cpX_V_QLp9Mg2ScLA8,20546
|
1698
1698
|
fastlife/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1699
|
-
fastlife/views/pydantic_form.py,sha256=
|
1700
|
-
fastlifeweb-0.
|
1701
|
-
fastlifeweb-0.
|
1702
|
-
fastlifeweb-0.
|
1703
|
-
fastlifeweb-0.
|
1699
|
+
fastlife/views/pydantic_form.py,sha256=WjRqtwc30g3W_4vqkVj0zzaK-vEWX4ZbtBV5vMpT9Xo,1267
|
1700
|
+
fastlifeweb-0.11.0.dist-info/LICENSE,sha256=F75xSseSKMwqzFj8rswYU6NWS3VoWOc_gY3fJYf9_LI,1504
|
1701
|
+
fastlifeweb-0.11.0.dist-info/METADATA,sha256=wzlejQlx8pvO4_sjNGkntJHTdKEx28RHTk_20h8J9oA,2006
|
1702
|
+
fastlifeweb-0.11.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1703
|
+
fastlifeweb-0.11.0.dist-info/RECORD,,
|
fastlife/configurator/base.py
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
from typing import TYPE_CHECKING, Any, Callable, Coroutine
|
2
|
-
|
3
|
-
from fastapi import Request as BaseRequest
|
4
|
-
from fastapi.routing import APIRoute
|
5
|
-
from starlette.responses import Response
|
6
|
-
|
7
|
-
if TYPE_CHECKING:
|
8
|
-
from .registry import AppRegistry # coverage: ignore
|
9
|
-
|
10
|
-
|
11
|
-
class FastlifeRequest(BaseRequest):
|
12
|
-
def __init__(self, registry: "AppRegistry", request: BaseRequest) -> None:
|
13
|
-
super().__init__(request.scope, request.receive)
|
14
|
-
self.registry = registry
|
15
|
-
|
16
|
-
|
17
|
-
class FastlifeRoute(APIRoute):
|
18
|
-
registry: "AppRegistry" = None # type: ignore
|
19
|
-
|
20
|
-
def get_route_handler( # type: ignore
|
21
|
-
self,
|
22
|
-
) -> Callable[[FastlifeRequest], Coroutine[Any, Any, Response]]:
|
23
|
-
orig_route_handler = super().get_route_handler()
|
24
|
-
|
25
|
-
async def route_handler(request: BaseRequest) -> FastlifeRequest:
|
26
|
-
req = FastlifeRequest(self.registry, request)
|
27
|
-
return await orig_route_handler(req) # type: ignore
|
28
|
-
|
29
|
-
return route_handler # type: ignore
|
fastlife/templates/__init__.py
DELETED
File without changes
|
File without changes
|
File without changes
|