python-fasthtml 0.3.3__tar.gz → 0.3.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.3.3/python_fasthtml.egg-info → python-fasthtml-0.3.4}/PKG-INFO +1 -1
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/__init__.py +1 -1
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/_modidx.py +9 -1
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/core.py +67 -12
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4/python_fasthtml.egg-info}/PKG-INFO +1 -1
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/settings.ini +1 -1
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/CONTRIBUTING.md +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/LICENSE +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/MANIFEST.in +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/README.md +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/authmw.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/cli.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/common.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/components.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/components.pyi +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/fastapp.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/ft.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/js.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/live_reload.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/oauth.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/starlette.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/svg.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/toaster.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/xtend.py +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/fasthtml/xtend.pyi +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/SOURCES.txt +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/dependency_links.txt +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/entry_points.txt +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/not-zip-safe +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/requires.txt +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/top_level.txt +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/setup.cfg +0 -0
- {python-fasthtml-0.3.3 → python-fasthtml-0.3.4}/setup.py +0 -0
|
@@ -27,6 +27,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
27
27
|
'fasthtml.core.FastHTML.__init__': ('api/core.html#fasthtml.__init__', 'fasthtml/core.py'),
|
|
28
28
|
'fasthtml.core.FastHTML.route': ('api/core.html#fasthtml.route', 'fasthtml/core.py'),
|
|
29
29
|
'fasthtml.core.FastHTML.ws': ('api/core.html#fasthtml.ws', 'fasthtml/core.py'),
|
|
30
|
+
'fasthtml.core.HTTPConnection.url_path_for': ( 'api/core.html#httpconnection.url_path_for',
|
|
31
|
+
'fasthtml/core.py'),
|
|
30
32
|
'fasthtml.core.HtmxHeaders': ('api/core.html#htmxheaders', 'fasthtml/core.py'),
|
|
31
33
|
'fasthtml.core.HtmxHeaders.__bool__': ('api/core.html#htmxheaders.__bool__', 'fasthtml/core.py'),
|
|
32
34
|
'fasthtml.core.HttpHeader': ('api/core.html#httpheader', 'fasthtml/core.py'),
|
|
@@ -39,6 +41,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
39
41
|
'fasthtml.core.RouterX.__init__': ('api/core.html#routerx.__init__', 'fasthtml/core.py'),
|
|
40
42
|
'fasthtml.core.RouterX.add_route': ('api/core.html#routerx.add_route', 'fasthtml/core.py'),
|
|
41
43
|
'fasthtml.core.RouterX.add_ws': ('api/core.html#routerx.add_ws', 'fasthtml/core.py'),
|
|
44
|
+
'fasthtml.core.StringConvertor.to_string': ('api/core.html#stringconvertor.to_string', 'fasthtml/core.py'),
|
|
42
45
|
'fasthtml.core.WS_RouteX': ('api/core.html#ws_routex', 'fasthtml/core.py'),
|
|
43
46
|
'fasthtml.core.WS_RouteX.__init__': ('api/core.html#ws_routex.__init__', 'fasthtml/core.py'),
|
|
44
47
|
'fasthtml.core._SessionMiddleware': ('api/core.html#_sessionmiddleware', 'fasthtml/core.py'),
|
|
@@ -46,6 +49,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
46
49
|
'fasthtml/core.py'),
|
|
47
50
|
'fasthtml.core._annotations': ('api/core.html#_annotations', 'fasthtml/core.py'),
|
|
48
51
|
'fasthtml.core._find_p': ('api/core.html#_find_p', 'fasthtml/core.py'),
|
|
52
|
+
'fasthtml.core._find_targets': ('api/core.html#_find_targets', 'fasthtml/core.py'),
|
|
49
53
|
'fasthtml.core._find_wsp': ('api/core.html#_find_wsp', 'fasthtml/core.py'),
|
|
50
54
|
'fasthtml.core._fix_anno': ('api/core.html#_fix_anno', 'fasthtml/core.py'),
|
|
51
55
|
'fasthtml.core._form_arg': ('api/core.html#_form_arg', 'fasthtml/core.py'),
|
|
@@ -58,6 +62,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
58
62
|
'fasthtml.core._resp': ('api/core.html#_resp', 'fasthtml/core.py'),
|
|
59
63
|
'fasthtml.core._send_ws': ('api/core.html#_send_ws', 'fasthtml/core.py'),
|
|
60
64
|
'fasthtml.core._sig': ('api/core.html#_sig', 'fasthtml/core.py'),
|
|
65
|
+
'fasthtml.core._to_xml': ('api/core.html#_to_xml', 'fasthtml/core.py'),
|
|
66
|
+
'fasthtml.core._url_for': ('api/core.html#_url_for', 'fasthtml/core.py'),
|
|
61
67
|
'fasthtml.core._wrap_call': ('api/core.html#_wrap_call', 'fasthtml/core.py'),
|
|
62
68
|
'fasthtml.core._wrap_ex': ('api/core.html#_wrap_ex', 'fasthtml/core.py'),
|
|
63
69
|
'fasthtml.core._wrap_req': ('api/core.html#_wrap_req', 'fasthtml/core.py'),
|
|
@@ -66,6 +72,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
66
72
|
'fasthtml.core._xt_resp': ('api/core.html#_xt_resp', 'fasthtml/core.py'),
|
|
67
73
|
'fasthtml.core.cookie': ('api/core.html#cookie', 'fasthtml/core.py'),
|
|
68
74
|
'fasthtml.core.date': ('api/core.html#date', 'fasthtml/core.py'),
|
|
75
|
+
'fasthtml.core.decode_uri': ('api/core.html#decode_uri', 'fasthtml/core.py'),
|
|
69
76
|
'fasthtml.core.flat_xt': ('api/core.html#flat_xt', 'fasthtml/core.py'),
|
|
70
77
|
'fasthtml.core.form2dict': ('api/core.html#form2dict', 'fasthtml/core.py'),
|
|
71
78
|
'fasthtml.core.get_key': ('api/core.html#get_key', 'fasthtml/core.py'),
|
|
@@ -73,7 +80,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
73
80
|
'fasthtml.core.is_typeddict': ('api/core.html#is_typeddict', 'fasthtml/core.py'),
|
|
74
81
|
'fasthtml.core.reg_re_param': ('api/core.html#reg_re_param', 'fasthtml/core.py'),
|
|
75
82
|
'fasthtml.core.snake2hyphens': ('api/core.html#snake2hyphens', 'fasthtml/core.py'),
|
|
76
|
-
'fasthtml.core.str2int': ('api/core.html#str2int', 'fasthtml/core.py')
|
|
83
|
+
'fasthtml.core.str2int': ('api/core.html#str2int', 'fasthtml/core.py'),
|
|
84
|
+
'fasthtml.core.uri': ('api/core.html#uri', 'fasthtml/core.py')},
|
|
77
85
|
'fasthtml.fastapp': {},
|
|
78
86
|
'fasthtml.ft': {},
|
|
79
87
|
'fasthtml.js': {},
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
# %% auto 0
|
|
4
4
|
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmxscr', 'htmxwsscr', 'surrsrc', 'scopesrc', 'viewport', 'charset', 'all_meths',
|
|
5
5
|
'is_typeddict', 'is_namedtuple', 'date', 'snake2hyphens', 'HtmxHeaders', 'str2int', 'HttpHeader',
|
|
6
|
-
'form2dict', 'flat_xt', 'Beforeware', 'WS_RouteX', '
|
|
7
|
-
'reg_re_param', 'MiddlewareBase']
|
|
6
|
+
'form2dict', 'flat_xt', 'Beforeware', 'WS_RouteX', 'uri', 'decode_uri', 'RouteX', 'RouterX', 'get_key',
|
|
7
|
+
'FastHTML', 'cookie', 'reg_re_param', 'MiddlewareBase']
|
|
8
8
|
|
|
9
9
|
# %% ../nbs/api/00_core.ipynb
|
|
10
10
|
import json,uuid,inspect,types
|
|
@@ -20,9 +20,11 @@ from collections import namedtuple
|
|
|
20
20
|
from inspect import isfunction,ismethod,Parameter,get_annotations
|
|
21
21
|
from functools import wraps, partialmethod
|
|
22
22
|
from http import cookies
|
|
23
|
+
from urllib.parse import urlencode, parse_qs, quote, unquote
|
|
23
24
|
from copy import copy,deepcopy
|
|
24
25
|
from warnings import warn
|
|
25
26
|
from dateutil import parser as dtparse
|
|
27
|
+
from starlette.requests import HTTPConnection
|
|
26
28
|
|
|
27
29
|
from .starlette import *
|
|
28
30
|
|
|
@@ -103,7 +105,7 @@ def _fix_anno(t):
|
|
|
103
105
|
def _form_arg(k, v, d):
|
|
104
106
|
"Get type by accessing key `k` from `d`, and use to cast `v`"
|
|
105
107
|
if v is None: return
|
|
106
|
-
if not isinstance(v, str): return v
|
|
108
|
+
if not isinstance(v, (str,list,tuple)): return v
|
|
107
109
|
# This is the type we want to cast `v` to
|
|
108
110
|
anno = d.get(k, None)
|
|
109
111
|
if not anno: return v
|
|
@@ -258,6 +260,57 @@ class WS_RouteX(WebSocketRoute):
|
|
|
258
260
|
name=None, middleware=None, hdrs=None, before=None):
|
|
259
261
|
super().__init__(path, _ws_endp(recv, conn, disconn, hdrs, before), name=name, middleware=middleware)
|
|
260
262
|
|
|
263
|
+
# %% ../nbs/api/00_core.ipynb
|
|
264
|
+
def uri(_arg, **kwargs):
|
|
265
|
+
return f"{quote(_arg)}/{urlencode(kwargs, doseq=True)}"
|
|
266
|
+
|
|
267
|
+
# %% ../nbs/api/00_core.ipynb
|
|
268
|
+
def decode_uri(s):
|
|
269
|
+
arg,_,kw = s.partition('/')
|
|
270
|
+
return unquote(arg), {k:v[0] for k,v in parse_qs(kw).items()}
|
|
271
|
+
|
|
272
|
+
# %% ../nbs/api/00_core.ipynb
|
|
273
|
+
from starlette.convertors import StringConvertor
|
|
274
|
+
|
|
275
|
+
# %% ../nbs/api/00_core.ipynb
|
|
276
|
+
StringConvertor.regex = "[^/]*" # `+` replaced with `*`
|
|
277
|
+
|
|
278
|
+
@patch
|
|
279
|
+
def to_string(self:StringConvertor, value: str) -> str:
|
|
280
|
+
value = str(value)
|
|
281
|
+
assert "/" not in value, "May not contain path separators"
|
|
282
|
+
# assert value, "Must not be empty" # line removed due to errors
|
|
283
|
+
return value
|
|
284
|
+
|
|
285
|
+
# %% ../nbs/api/00_core.ipynb
|
|
286
|
+
@patch
|
|
287
|
+
def url_path_for(self:HTTPConnection, name: str, **path_params):
|
|
288
|
+
router: Router = self.scope["router"]
|
|
289
|
+
return router.url_path_for(name, **path_params)
|
|
290
|
+
|
|
291
|
+
# %% ../nbs/api/00_core.ipynb
|
|
292
|
+
_verbs = dict(get='hx-get', post='hx-post', put='hx-post', delete='hx-delete', patch='hx-patch', link='href')
|
|
293
|
+
|
|
294
|
+
def _url_for(req, t):
|
|
295
|
+
if callable(t): t = t.__routename__
|
|
296
|
+
kw = {}
|
|
297
|
+
if t.find('/')>-1 and (t.find('?')<0 or t.find('/')<t.find('?')): t,kw = decode_uri(t)
|
|
298
|
+
t,m,q = t.partition('?')
|
|
299
|
+
return f"{req.url_path_for(t, **kw)}{m}{q}"
|
|
300
|
+
|
|
301
|
+
def _find_targets(req, resp):
|
|
302
|
+
if isinstance(resp, tuple):
|
|
303
|
+
for o in resp: _find_targets(req, o)
|
|
304
|
+
if isinstance(resp, FT):
|
|
305
|
+
for o in resp.children: _find_targets(req, o)
|
|
306
|
+
for k,v in _verbs.items():
|
|
307
|
+
t = resp.attrs.pop(k, None)
|
|
308
|
+
if t: resp.attrs[v] = _url_for(req, t)
|
|
309
|
+
|
|
310
|
+
def _to_xml(req, resp, indent):
|
|
311
|
+
_find_targets(req, resp)
|
|
312
|
+
return to_xml(resp, indent)
|
|
313
|
+
|
|
261
314
|
# %% ../nbs/api/00_core.ipynb
|
|
262
315
|
def _xt_resp(req, resp):
|
|
263
316
|
if not isinstance(resp, tuple): resp = (resp,)
|
|
@@ -269,7 +322,7 @@ def _xt_resp(req, resp):
|
|
|
269
322
|
if resp and 'hx-request' not in req.headers and not any(getattr(o, 'tag', '')=='html' for o in resp):
|
|
270
323
|
if not titles: titles = [Title('FastHTML page')]
|
|
271
324
|
resp = Html(Head(*titles, *flat_xt(req.hdrs)), Body(bdy, *flat_xt(req.ftrs), **req.bodykw), **req.htmlkw)
|
|
272
|
-
return HTMLResponse(
|
|
325
|
+
return HTMLResponse(_to_xml(req, resp, indent=fh_cfg.indent), headers=http_hdrs)
|
|
273
326
|
|
|
274
327
|
# %% ../nbs/api/00_core.ipynb
|
|
275
328
|
def _resp(req, resp, cls=empty):
|
|
@@ -406,17 +459,19 @@ class FastHTML(Starlette):
|
|
|
406
459
|
self.router = RouterX(routes, on_startup=on_startup, on_shutdown=on_shutdown, lifespan=lifespan,
|
|
407
460
|
hdrs=hdrs, ftrs=ftrs, before=before, after=after, htmlkw=htmlkw, **bodykw)
|
|
408
461
|
|
|
409
|
-
def route(self, path:str, methods=None, name=None, include_in_schema=True):
|
|
462
|
+
def route(self, path:str=None, methods=None, name=None, include_in_schema=True):
|
|
410
463
|
"Add a route at `path`; the function name is the default method"
|
|
464
|
+
pathstr = None if callable(path) else path
|
|
411
465
|
def f(func):
|
|
412
|
-
n = name
|
|
413
|
-
if methods:
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
self.router.add_route(
|
|
466
|
+
n,fn,p = name,func.__name__,pathstr
|
|
467
|
+
if methods: m = [methods] if isinstance(methods,str) else methods
|
|
468
|
+
else: m = [fn] if fn in _verbs else ['post']
|
|
469
|
+
if not n: n = fn
|
|
470
|
+
if not p: p = '/'+fn
|
|
471
|
+
self.router.add_route(p, func, methods=m, name=n, include_in_schema=include_in_schema)
|
|
472
|
+
func.__routename__ = n
|
|
418
473
|
return func
|
|
419
|
-
return f
|
|
474
|
+
return f(path) if callable(path) else f
|
|
420
475
|
|
|
421
476
|
def ws(self, path:str, conn=None, disconn=None, name=None):
|
|
422
477
|
def f(func):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[DEFAULT]
|
|
2
2
|
repo = fasthtml
|
|
3
3
|
lib_name = fasthtml
|
|
4
|
-
version = 0.3.
|
|
4
|
+
version = 0.3.4
|
|
5
5
|
min_python = 3.10
|
|
6
6
|
license = apache2
|
|
7
7
|
requirements = fastcore>=1.6.7 python-dateutil starlette>0.33 oauthlib itsdangerous uvicorn[standard]>=0.30 httpx fastlite>=0.0.6 python-multipart beautifulsoup4
|
|
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.3.3 → python-fasthtml-0.3.4}/python_fasthtml.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|