python-fasthtml 0.13.0__tar.gz → 0.13.1__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.
Files changed (39) hide show
  1. {python_fasthtml-0.13.0/python_fasthtml.egg-info → python_fasthtml-0.13.1}/PKG-INFO +1 -1
  2. python_fasthtml-0.13.1/fasthtml/__init__.py +2 -0
  3. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/_modidx.py +14 -1
  4. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/core.py +40 -17
  5. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1/python_fasthtml.egg-info}/PKG-INFO +1 -1
  6. python_fasthtml-0.13.0/fasthtml/__init__.py +0 -2
  7. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/CONTRIBUTING.md +0 -0
  8. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/LICENSE +0 -0
  9. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/MANIFEST.in +0 -0
  10. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/README.md +0 -0
  11. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/authmw.py +0 -0
  12. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/basics.py +0 -0
  13. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/cli.py +0 -0
  14. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/common.py +0 -0
  15. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/components.py +0 -0
  16. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/components.pyi +0 -0
  17. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/core.pyi +0 -0
  18. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/fastapp.py +0 -0
  19. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/ft.py +0 -0
  20. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/js.py +0 -0
  21. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/jupyter.py +0 -0
  22. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/katex.js +0 -0
  23. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/live_reload.py +0 -0
  24. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/oauth.py +0 -0
  25. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/pico.py +0 -0
  26. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/starlette.py +0 -0
  27. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/stripe_otp.py +0 -0
  28. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/svg.py +0 -0
  29. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/toaster.py +0 -0
  30. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/xtend.py +0 -0
  31. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/fasthtml/xtend.pyi +0 -0
  32. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/pyproject.toml +0 -0
  33. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/python_fasthtml.egg-info/SOURCES.txt +0 -0
  34. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/python_fasthtml.egg-info/dependency_links.txt +0 -0
  35. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/python_fasthtml.egg-info/entry_points.txt +0 -0
  36. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/python_fasthtml.egg-info/requires.txt +0 -0
  37. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/python_fasthtml.egg-info/top_level.txt +0 -0
  38. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/setup.cfg +0 -0
  39. {python_fasthtml-0.13.0 → python_fasthtml-0.13.1}/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.0
3
+ Version: 0.13.1
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
@@ -0,0 +1,2 @@
1
+ __version__ = "0.13.1"
2
+ from .core import *
@@ -50,8 +50,11 @@ d = { 'settings': { 'branch': 'main',
50
50
  'fasthtml.core.FastHTML._add_ws': ('api/core.html#fasthtml._add_ws', 'fasthtml/core.py'),
51
51
  'fasthtml.core.FastHTML._endp': ('api/core.html#fasthtml._endp', 'fasthtml/core.py'),
52
52
  'fasthtml.core.FastHTML.add_route': ('api/core.html#fasthtml.add_route', 'fasthtml/core.py'),
53
+ 'fasthtml.core.FastHTML.add_websocket_route': ( 'api/core.html#fasthtml.add_websocket_route',
54
+ 'fasthtml/core.py'),
53
55
  'fasthtml.core.FastHTML.devtools_json': ('api/core.html#fasthtml.devtools_json', 'fasthtml/core.py'),
54
56
  'fasthtml.core.FastHTML.get_client': ('api/core.html#fasthtml.get_client', 'fasthtml/core.py'),
57
+ 'fasthtml.core.FastHTML.on_event': ('api/core.html#fasthtml.on_event', 'fasthtml/core.py'),
55
58
  'fasthtml.core.FastHTML.route': ('api/core.html#fasthtml.route', 'fasthtml/core.py'),
56
59
  'fasthtml.core.FastHTML.set_lifespan': ('api/core.html#fasthtml.set_lifespan', 'fasthtml/core.py'),
57
60
  'fasthtml.core.FastHTML.setup_ws': ('api/core.html#fasthtml.setup_ws', 'fasthtml/core.py'),
@@ -73,6 +76,11 @@ d = { 'settings': { 'branch': 'main',
73
76
  'fasthtml.core.HttpHeader': ('api/core.html#httpheader', 'fasthtml/core.py'),
74
77
  'fasthtml.core.JSONResponse': ('api/core.html#jsonresponse', 'fasthtml/core.py'),
75
78
  'fasthtml.core.JSONResponse.render': ('api/core.html#jsonresponse.render', 'fasthtml/core.py'),
79
+ 'fasthtml.core.Lifespan': ('api/core.html#lifespan', 'fasthtml/core.py'),
80
+ 'fasthtml.core.Lifespan.__call__': ('api/core.html#lifespan.__call__', 'fasthtml/core.py'),
81
+ 'fasthtml.core.Lifespan.__init__': ('api/core.html#lifespan.__init__', 'fasthtml/core.py'),
82
+ 'fasthtml.core.Lifespan._run': ('api/core.html#lifespan._run', 'fasthtml/core.py'),
83
+ 'fasthtml.core.Lifespan.on_event': ('api/core.html#lifespan.on_event', 'fasthtml/core.py'),
76
84
  'fasthtml.core.MiddlewareBase': ('api/core.html#middlewarebase', 'fasthtml/core.py'),
77
85
  'fasthtml.core.MiddlewareBase.__call__': ('api/core.html#middlewarebase.__call__', 'fasthtml/core.py'),
78
86
  'fasthtml.core.Redirect': ('api/core.html#redirect', 'fasthtml/core.py'),
@@ -87,6 +95,12 @@ d = { 'settings': { 'branch': 'main',
87
95
  'fasthtml.core.StaticNoCache.file_response': ( 'api/core.html#staticnocache.file_response',
88
96
  'fasthtml/core.py'),
89
97
  'fasthtml.core.StringConvertor.to_string': ('api/core.html#stringconvertor.to_string', 'fasthtml/core.py'),
98
+ 'fasthtml.core._LifespanCtx': ('api/core.html#_lifespanctx', 'fasthtml/core.py'),
99
+ 'fasthtml.core._LifespanCtx.__aenter__': ('api/core.html#_lifespanctx.__aenter__', 'fasthtml/core.py'),
100
+ 'fasthtml.core._LifespanCtx.__aexit__': ('api/core.html#_lifespanctx.__aexit__', 'fasthtml/core.py'),
101
+ 'fasthtml.core._LifespanCtx.__aiter__': ('api/core.html#_lifespanctx.__aiter__', 'fasthtml/core.py'),
102
+ 'fasthtml.core._LifespanCtx.__anext__': ('api/core.html#_lifespanctx.__anext__', 'fasthtml/core.py'),
103
+ 'fasthtml.core._LifespanCtx.__init__': ('api/core.html#_lifespanctx.__init__', 'fasthtml/core.py'),
90
104
  'fasthtml.core._add_ids': ('api/core.html#_add_ids', 'fasthtml/core.py'),
91
105
  'fasthtml.core._annotations': ('api/core.html#_annotations', 'fasthtml/core.py'),
92
106
  'fasthtml.core._apply_ft': ('api/core.html#_apply_ft', 'fasthtml/core.py'),
@@ -104,7 +118,6 @@ d = { 'settings': { 'branch': 'main',
104
118
  'fasthtml.core._is_body': ('api/core.html#_is_body', 'fasthtml/core.py'),
105
119
  'fasthtml.core._is_ft_resp': ('api/core.html#_is_ft_resp', 'fasthtml/core.py'),
106
120
  'fasthtml.core._list': ('api/core.html#_list', 'fasthtml/core.py'),
107
- 'fasthtml.core._mk_lifespan': ('api/core.html#_mk_lifespan', 'fasthtml/core.py'),
108
121
  'fasthtml.core._mk_list': ('api/core.html#_mk_list', 'fasthtml/core.py'),
109
122
  'fasthtml.core._mk_locfunc': ('api/core.html#_mk_locfunc', 'fasthtml/core.py'),
110
123
  'fasthtml.core._params': ('api/core.html#_params', 'fasthtml/core.py'),
@@ -7,9 +7,9 @@ __all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc',
7
7
  'charset', 'cors_allow', 'iframe_scr', 'all_meths', 'devtools_loc', 'parsed_date', 'snake2hyphens',
8
8
  'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', 'ApiReturn', 'JSONResponse',
9
9
  'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'uri', 'decode_uri', 'flat_tuple', 'noop_body',
10
- 'respond', 'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'FastHTML', 'HostRoute', 'nested_name',
11
- 'serve', 'Client', 'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', 'MiddlewareBase',
12
- 'FtResponse', 'unqid']
10
+ 'respond', 'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'Lifespan', 'FastHTML', 'HostRoute',
11
+ 'nested_name', 'serve', 'Client', 'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache',
12
+ '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
@@ -566,17 +566,32 @@ iframe_scr = Script(NotStr("""
566
566
  document.body.addEventListener('htmx:wsAfterMessage', sendmsg);
567
567
  };"""))
568
568
 
569
- # %% ../nbs/api/00_core.ipynb #d370ef59
570
- def _mk_lifespan(ls, on_startup, on_shutdown):
571
- if not on_startup and not on_shutdown: return ls
572
- @contextlib.asynccontextmanager
573
- async def _ls(app):
574
- for f in listify(on_startup): await _handle(f)
575
- if ls:
576
- async with ls(app): yield
569
+ # %% ../nbs/api/00_core.ipynb #17ced9a3
570
+ class _LifespanCtx:
571
+ def __init__(self, gen): self.gen = gen
572
+ async def __aenter__(self): return await anext(self.gen)
573
+ async def __aexit__(self, *_):
574
+ try: await anext(self.gen)
575
+ except StopAsyncIteration: pass
576
+ def __aiter__(self): return self.gen
577
+ async def __anext__(self): return await self.gen.__anext__()
578
+
579
+ class Lifespan:
580
+ def __init__(self, startup=None, shutdown=None, ls=None):
581
+ startup,shutdown = listify(startup),listify(shutdown)
582
+ store_attr()
583
+
584
+ def __call__(self, app): return _LifespanCtx(self._run(app))
585
+
586
+ async def _run(self, app):
587
+ for f in self.startup: await _handle(f)
588
+ if self.ls:
589
+ async for state in self.ls(app): yield state
577
590
  else: yield
578
- for f in listify(on_shutdown): await _handle(f)
579
- return _ls
591
+ for f in self.shutdown: await _handle(f)
592
+
593
+ def on_event(self, event_type):
594
+ return lambda f: (getattr(self, event_type)).append(f)
580
595
 
581
596
  # %% ../nbs/api/00_core.ipynb #3327a1e9
582
597
  class FastHTML(Starlette):
@@ -598,8 +613,8 @@ class FastHTML(Starlette):
598
613
  from IPython.display import display,HTML
599
614
  if nb_hdrs: display(HTML(to_xml(tuple(hdrs))))
600
615
  middleware.append(cors_allow)
601
- lifespan = _mk_lifespan(lifespan, on_startup, on_shutdown)
602
- self.lifespan,self.hdrs,self.ftrs = lifespan,hdrs,ftrs
616
+ self.lifespan = Lifespan(on_startup, on_shutdown, lifespan)
617
+ self.hdrs,self.ftrs = hdrs,ftrs
603
618
  self.body_wrap,self.before,self.after,self.htmlkw,self.bodykw = body_wrap,before,after,htmlkw,bodykw
604
619
  self.secret_key = get_key(secret_key, key_fname)
605
620
  if sess_cls:
@@ -609,10 +624,12 @@ class FastHTML(Starlette):
609
624
  middleware.append(sess)
610
625
  exception_handlers = ifnone(exception_handlers, {})
611
626
  if 404 not in exception_handlers:
612
- def _not_found(req, exc): return Response('404 Not Found', status_code=404)
627
+ def _not_found(req, exc): return Response('404 Not Found', status_code=404)
613
628
  exception_handlers[404] = _not_found
614
629
  excs = {k:_wrap_ex(v, k, hdrs, ftrs, htmlkw, bodykw, body_wrap=body_wrap) for k,v in exception_handlers.items()}
615
- super().__init__(debug, routes, middleware=middleware, exception_handlers=excs, lifespan=lifespan)
630
+ super().__init__(debug, routes, middleware=middleware, exception_handlers=excs, lifespan=self.lifespan)
631
+
632
+ def on_event(self, event_type): return self.lifespan.on_event(event_type)
616
633
 
617
634
  # %% ../nbs/api/00_core.ipynb #dce68049
618
635
  class HostRoute(Route):
@@ -691,6 +708,12 @@ def ws(self:FastHTML, path:str, conn=None, disconn=None, name=None, middleware=N
691
708
  def f(func=noop): return self._add_ws(func, path, conn, disconn, name=name, middleware=middleware)
692
709
  return f
693
710
 
711
+ # %% ../nbs/api/00_core.ipynb #j6ete5u68fo
712
+ @patch
713
+ def add_websocket_route(self:FastHTML, path, func, conn=None, disconn=None, name=None, middleware=None):
714
+ "Add a websocket route at `path` (Starlette-compatible API)"
715
+ return self._add_ws(func, path, conn, disconn, name=name, middleware=middleware)
716
+
694
717
  # %% ../nbs/api/00_core.ipynb #919618c3
695
718
  def _mk_locfunc(f, p, app=None):
696
719
  "Create a location function wrapper with route path and to() method"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fasthtml
3
- Version: 0.13.0
3
+ Version: 0.13.1
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
@@ -1,2 +0,0 @@
1
- __version__ = "0.13.0"
2
- from .core import *