python-fasthtml 0.13.2__tar.gz → 0.13.4__tar.gz
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.
- {python_fasthtml-0.13.2/python_fasthtml.egg-info → python_fasthtml-0.13.4}/PKG-INFO +2 -2
- python_fasthtml-0.13.4/fasthtml/__init__.py +2 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/_modidx.py +5 -1
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/core.py +50 -15
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/pyproject.toml +3 -1
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4/python_fasthtml.egg-info}/PKG-INFO +2 -2
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/requires.txt +1 -1
- python_fasthtml-0.13.2/fasthtml/__init__.py +0 -2
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/CONTRIBUTING.md +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/LICENSE +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/MANIFEST.in +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/README.md +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/authmw.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/basics.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/cli.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/common.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/components.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/components.pyi +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/core.pyi +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/fastapp.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/ft.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/js.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/jupyter.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/katex.js +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/live_reload.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/oauth.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/pico.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/starlette.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/stripe_otp.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/svg.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/toaster.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/xtend.py +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/fasthtml/xtend.pyi +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/SOURCES.txt +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/dependency_links.txt +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/entry_points.txt +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/top_level.txt +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/setup.cfg +0 -0
- {python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/tests/test_toaster.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fasthtml
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.4
|
|
4
4
|
Summary: The fastest way to create an HTML app
|
|
5
5
|
Author-email: Jeremy Howard and contributors <github@jhoward.fastmail.fm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
15
15
|
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: fastcore>=1.12.
|
|
18
|
+
Requires-Dist: fastcore>=1.12.41
|
|
19
19
|
Requires-Dist: python-dateutil
|
|
20
20
|
Requires-Dist: starlette~=1.0
|
|
21
21
|
Requires-Dist: oauthlib
|
|
@@ -40,6 +40,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
40
40
|
'fasthtml.core.ApiReturn.__init__': ('api/core.html#apireturn.__init__', 'fasthtml/core.py'),
|
|
41
41
|
'fasthtml.core.Beforeware': ('api/core.html#beforeware', 'fasthtml/core.py'),
|
|
42
42
|
'fasthtml.core.Beforeware.__init__': ('api/core.html#beforeware.__init__', 'fasthtml/core.py'),
|
|
43
|
+
'fasthtml.core.Beforeware.__repr__': ('api/core.html#beforeware.__repr__', 'fasthtml/core.py'),
|
|
43
44
|
'fasthtml.core.Client': ('api/core.html#client', 'fasthtml/core.py'),
|
|
44
45
|
'fasthtml.core.Client.__init__': ('api/core.html#client.__init__', 'fasthtml/core.py'),
|
|
45
46
|
'fasthtml.core.Client._sync': ('api/core.html#client._sync', 'fasthtml/core.py'),
|
|
@@ -103,7 +104,6 @@ d = { 'settings': { 'branch': 'main',
|
|
|
103
104
|
'fasthtml.core._LifespanCtx.__init__': ('api/core.html#_lifespanctx.__init__', 'fasthtml/core.py'),
|
|
104
105
|
'fasthtml.core._add_ids': ('api/core.html#_add_ids', 'fasthtml/core.py'),
|
|
105
106
|
'fasthtml.core._annotations': ('api/core.html#_annotations', 'fasthtml/core.py'),
|
|
106
|
-
'fasthtml.core._apply_ft': ('api/core.html#_apply_ft', 'fasthtml/core.py'),
|
|
107
107
|
'fasthtml.core._canonical': ('api/core.html#_canonical', 'fasthtml/core.py'),
|
|
108
108
|
'fasthtml.core._check_anno': ('api/core.html#_check_anno', 'fasthtml/core.py'),
|
|
109
109
|
'fasthtml.core._find_p': ('api/core.html#_find_p', 'fasthtml/core.py'),
|
|
@@ -133,6 +133,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
133
133
|
'fasthtml.core._wrap_ws': ('api/core.html#_wrap_ws', 'fasthtml/core.py'),
|
|
134
134
|
'fasthtml.core._ws_endp': ('api/core.html#_ws_endp', 'fasthtml/core.py'),
|
|
135
135
|
'fasthtml.core._xt_cts': ('api/core.html#_xt_cts', 'fasthtml/core.py'),
|
|
136
|
+
'fasthtml.core.add_sig_param': ('api/core.html#add_sig_param', 'fasthtml/core.py'),
|
|
136
137
|
'fasthtml.core.cookie': ('api/core.html#cookie', 'fasthtml/core.py'),
|
|
137
138
|
'fasthtml.core.decode_uri': ('api/core.html#decode_uri', 'fasthtml/core.py'),
|
|
138
139
|
'fasthtml.core.def_hdrs': ('api/core.html#def_hdrs', 'fasthtml/core.py'),
|
|
@@ -140,6 +141,9 @@ d = { 'settings': { 'branch': 'main',
|
|
|
140
141
|
'fasthtml.core.flat_xt': ('api/core.html#flat_xt', 'fasthtml/core.py'),
|
|
141
142
|
'fasthtml.core.form2dict': ('api/core.html#form2dict', 'fasthtml/core.py'),
|
|
142
143
|
'fasthtml.core.get_key': ('api/core.html#get_key', 'fasthtml/core.py'),
|
|
144
|
+
'fasthtml.core.into': ('api/core.html#into', 'fasthtml/core.py'),
|
|
145
|
+
'fasthtml.core.into.__call__': ('api/core.html#into.__call__', 'fasthtml/core.py'),
|
|
146
|
+
'fasthtml.core.into.__init__': ('api/core.html#into.__init__', 'fasthtml/core.py'),
|
|
143
147
|
'fasthtml.core.is_full_page': ('api/core.html#is_full_page', 'fasthtml/core.py'),
|
|
144
148
|
'fasthtml.core.nested_name': ('api/core.html#nested_name', 'fasthtml/core.py'),
|
|
145
149
|
'fasthtml.core.noop_body': ('api/core.html#noop_body', 'fasthtml/core.py'),
|
|
@@ -9,7 +9,7 @@ __all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc',
|
|
|
9
9
|
'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'uri', 'decode_uri', 'flat_tuple', 'noop_body',
|
|
10
10
|
'respond', 'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'Lifespan', 'FastHTML', 'HostRoute',
|
|
11
11
|
'nested_name', 'serve', 'Client', 'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache',
|
|
12
|
-
'MiddlewareBase', 'FtResponse', 'unqid']
|
|
12
|
+
'add_sig_param', 'into', 'MiddlewareBase', 'FtResponse', 'unqid']
|
|
13
13
|
|
|
14
14
|
# %% ../nbs/api/00_core.ipynb #23503b9e
|
|
15
15
|
import json,uuid,inspect,types,asyncio,inspect,random,contextlib,httpx,itsdangerous,uvicorn
|
|
@@ -163,12 +163,15 @@ async def parse_form(req: Request) -> FormData:
|
|
|
163
163
|
return await req.json() if ctype == 'application/json' else await req.form()
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
# %% ../nbs/api/00_core.ipynb #
|
|
166
|
+
# %% ../nbs/api/00_core.ipynb #0caedd04
|
|
167
167
|
async def _from_body(conn, p, data):
|
|
168
168
|
"Create an instance of the annotated type from pre-parsed `data`"
|
|
169
169
|
anno = p.annotation
|
|
170
170
|
ctor = getattr(anno, '__from_request__', None)
|
|
171
|
-
if ctor:
|
|
171
|
+
if ctor:
|
|
172
|
+
ps = {k:v for k,v in _params(ctor).items() if k != 'cls'}
|
|
173
|
+
kwargs = await _find_ps(conn, data, conn.headers, ps)
|
|
174
|
+
return await maybe_await(ctor(**kwargs))
|
|
172
175
|
d = _annotations(anno)
|
|
173
176
|
cargs = {k: _form_arg(k, v, d) for k, v in data.items() if not d or k in d}
|
|
174
177
|
return anno(**cargs)
|
|
@@ -184,10 +187,12 @@ class ApiReturn:
|
|
|
184
187
|
# %% ../nbs/api/00_core.ipynb #7cc39ba9
|
|
185
188
|
class JSONResponse(JSONResponseOrig):
|
|
186
189
|
"Same as starlette's version, but auto-stringifies non serializable types"
|
|
187
|
-
def render(self, content:
|
|
188
|
-
|
|
190
|
+
def render(self, content:Any)->bytes:
|
|
191
|
+
def _default(o): return list(o) if is_listy(o) else str(o)
|
|
192
|
+
res = json.dumps(content, ensure_ascii=False, allow_nan=False, indent=None, separators=(",",":"), default=_default)
|
|
189
193
|
return res.encode("utf-8")
|
|
190
194
|
|
|
195
|
+
|
|
191
196
|
# %% ../nbs/api/00_core.ipynb #5fa96e3a
|
|
192
197
|
async def _find_p(conn, data, hdrs, arg:str, p:Parameter):
|
|
193
198
|
"In `data` find param named `arg` of type in `p` (`arg` is ignored for body types)"
|
|
@@ -207,7 +212,7 @@ async def _find_p(conn, data, hdrs, arg:str, p:Parameter):
|
|
|
207
212
|
if anno is empty:
|
|
208
213
|
if arg.lower()=='ws' or 'request'.startswith(arg.lower()): return conn
|
|
209
214
|
if 'session'.startswith(arg.lower()): return conn.scope.get('session', {})
|
|
210
|
-
if arg.lower()=='scope': return
|
|
215
|
+
if arg.lower()=='scope': return conn.scope
|
|
211
216
|
if arg.lower()=='data': return data
|
|
212
217
|
if arg.lower()=='htmx': return _get_htmx(hdrs)
|
|
213
218
|
if arg.lower()=='app': return conn.scope['app']
|
|
@@ -260,6 +265,7 @@ def flat_xt(lst):
|
|
|
260
265
|
# %% ../nbs/api/00_core.ipynb #aacff5ac
|
|
261
266
|
class Beforeware:
|
|
262
267
|
def __init__(self, f, skip=None): self.f,self.skip = f,skip or []
|
|
268
|
+
def __repr__(self): return f'Beforeware({self.f}, skip={self.skip})'
|
|
263
269
|
|
|
264
270
|
# %% ../nbs/api/00_core.ipynb #78c3c357
|
|
265
271
|
async def _handle(f, *args, **kwargs):
|
|
@@ -267,7 +273,7 @@ async def _handle(f, *args, **kwargs):
|
|
|
267
273
|
|
|
268
274
|
# %% ../nbs/api/00_core.ipynb #ad0f0e87
|
|
269
275
|
async def _wrap_ws(ws, data, params):
|
|
270
|
-
hdrs = Headers({k.lower():v for k,v in data.pop('HEADERS', {}).items()})
|
|
276
|
+
hdrs = Headers({k.lower():v for k,v in data.pop('HEADERS', {}).items() if v is not None})
|
|
271
277
|
return await _find_ps(ws, data, hdrs, params)
|
|
272
278
|
|
|
273
279
|
# %% ../nbs/api/00_core.ipynb #dcc15129
|
|
@@ -365,16 +371,8 @@ def _find_targets(req, resp):
|
|
|
365
371
|
t = resp.attrs.pop(k, None)
|
|
366
372
|
if t: resp.attrs[v] = _url_for(req, t)
|
|
367
373
|
|
|
368
|
-
def _apply_ft(o):
|
|
369
|
-
"Apply FastTag transformation recursively to object `o`"
|
|
370
|
-
if isinstance(o, tuple): o = tuple(_apply_ft(c) for c in o)
|
|
371
|
-
if hasattr(o, '__ft__'): o = o.__ft__()
|
|
372
|
-
if isinstance(o, FT): o.children = tuple(_apply_ft(c) for c in o.children)
|
|
373
|
-
return o
|
|
374
|
-
|
|
375
374
|
def _to_xml(req, resp, indent):
|
|
376
375
|
"Convert response to XML string with target URL resolution"
|
|
377
|
-
resp = _apply_ft(resp)
|
|
378
376
|
_find_targets(req, resp)
|
|
379
377
|
return to_xml(resp, indent=indent)
|
|
380
378
|
|
|
@@ -904,6 +902,43 @@ class StaticNoCache(StaticFiles):
|
|
|
904
902
|
resp.headers.setdefault("Cache-Control", "no-cache")
|
|
905
903
|
return resp
|
|
906
904
|
|
|
905
|
+
# %% ../nbs/api/00_core.ipynb #7189daf8
|
|
906
|
+
from functools import wraps
|
|
907
|
+
from inspect import signature, isawaitable
|
|
908
|
+
|
|
909
|
+
# %% ../nbs/api/00_core.ipynb #7eed23b7
|
|
910
|
+
def add_sig_param(f, name, typ=NoneType, kind=Parameter.KEYWORD_ONLY, default=Parameter.empty):
|
|
911
|
+
"Add a parameter to a function's signature"
|
|
912
|
+
sig = signature(f)
|
|
913
|
+
if name in sig.parameters: return f
|
|
914
|
+
kw = {} if default is Parameter.empty else {'default': default}
|
|
915
|
+
new_params = list(sig.parameters.values()) + [Parameter(name, kind, **kw)]
|
|
916
|
+
f.__signature__ = sig.replace(parameters=new_params)
|
|
917
|
+
f.__annotations__[name] = typ
|
|
918
|
+
return f
|
|
919
|
+
|
|
920
|
+
# %% ../nbs/api/00_core.ipynb #9e5a9e88
|
|
921
|
+
class into:
|
|
922
|
+
"Decorator to pass a route's return value into `func`, with keyword params added to the route signature"
|
|
923
|
+
def __init__(self, func):
|
|
924
|
+
self.func = func
|
|
925
|
+
self.params = {k:p for k,p in signature(func).parameters.items()
|
|
926
|
+
if p.kind not in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD)}
|
|
927
|
+
|
|
928
|
+
def __call__(self, f):
|
|
929
|
+
@wraps(f)
|
|
930
|
+
async def _inner(*args, **kw):
|
|
931
|
+
extra = {k: kw.pop(k, None) for k in self.params}
|
|
932
|
+
res = f(*args, **kw)
|
|
933
|
+
if isawaitable(res): res = await res
|
|
934
|
+
res = self.func(*tuplify(res), **extra)
|
|
935
|
+
if isawaitable(res): res = await res
|
|
936
|
+
return res
|
|
937
|
+
for k,p in self.params.items():
|
|
938
|
+
anno = p.annotation if p.annotation is not Parameter.empty else NoneType
|
|
939
|
+
add_sig_param(_inner, k, anno, default=p.default)
|
|
940
|
+
return _inner
|
|
941
|
+
|
|
907
942
|
# %% ../nbs/api/00_core.ipynb #1960d7ff
|
|
908
943
|
class MiddlewareBase:
|
|
909
944
|
async def __call__(self, scope, receive, send) -> None:
|
|
@@ -12,7 +12,7 @@ license = {text = "Apache-2.0"}
|
|
|
12
12
|
authors = [{name = "Jeremy Howard and contributors", email = "github@jhoward.fastmail.fm"}]
|
|
13
13
|
keywords = ['nbdev', 'jupyter', 'notebook', 'python']
|
|
14
14
|
classifiers = ["Natural Language :: English", "Intended Audience :: Developers", "Development Status :: 3 - Alpha", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only"]
|
|
15
|
-
dependencies = ['fastcore>=1.12.
|
|
15
|
+
dependencies = ['fastcore>=1.12.41', 'python-dateutil', 'starlette~=1.0', 'oauthlib', 'itsdangerous', 'uvicorn[standard]>=0.30', 'httpx', 'fastlite>=0.1.1', 'python-multipart', 'beautifulsoup4']
|
|
16
16
|
|
|
17
17
|
[project.urls]
|
|
18
18
|
Repository = "https://github.com/AnswerDotAI/fasthtml"
|
|
@@ -36,6 +36,8 @@ version = {attr = "fasthtml.__version__"}
|
|
|
36
36
|
include = ["fasthtml"]
|
|
37
37
|
|
|
38
38
|
[tool.nbdev]
|
|
39
|
+
allowed_metadata_keys = ['solveit_dialog_mode', 'solveit_ver']
|
|
40
|
+
allowed_cell_metadata_keys = ["solveit_ai"]
|
|
39
41
|
jupyter_hooks = true
|
|
40
42
|
custom_sidebar = false
|
|
41
43
|
lib_path = "fasthtml"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-fasthtml
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.4
|
|
4
4
|
Summary: The fastest way to create an HTML app
|
|
5
5
|
Author-email: Jeremy Howard and contributors <github@jhoward.fastmail.fm>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
15
15
|
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: fastcore>=1.12.
|
|
18
|
+
Requires-Dist: fastcore>=1.12.41
|
|
19
19
|
Requires-Dist: python-dateutil
|
|
20
20
|
Requires-Dist: starlette~=1.0
|
|
21
21
|
Requires-Dist: oauthlib
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_fasthtml-0.13.2 → python_fasthtml-0.13.4}/python_fasthtml.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|