python-fasthtml 0.12.32__tar.gz → 0.12.34__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 (42) hide show
  1. {python_fasthtml-0.12.32/python_fasthtml.egg-info → python_fasthtml-0.12.34}/PKG-INFO +1 -1
  2. python_fasthtml-0.12.34/fasthtml/__init__.py +2 -0
  3. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/_modidx.py +1 -0
  4. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/cli.py +1 -1
  5. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/components.py +4 -3
  6. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/core.py +17 -7
  7. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/jupyter.py +5 -2
  8. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34/python_fasthtml.egg-info}/PKG-INFO +1 -1
  9. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/settings.ini +1 -1
  10. python_fasthtml-0.12.32/fasthtml/__init__.py +0 -2
  11. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/CONTRIBUTING.md +0 -0
  12. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/LICENSE +0 -0
  13. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/MANIFEST.in +0 -0
  14. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/README.md +0 -0
  15. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/authmw.py +0 -0
  16. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/basics.py +0 -0
  17. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/common.py +0 -0
  18. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/components.pyi +0 -0
  19. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/core.pyi +0 -0
  20. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/fastapp.py +0 -0
  21. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/ft.py +0 -0
  22. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/js.py +0 -0
  23. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/katex.js +0 -0
  24. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/live_reload.py +0 -0
  25. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/oauth.py +0 -0
  26. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/pico.py +0 -0
  27. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/starlette.py +0 -0
  28. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/stripe_otp.py +0 -0
  29. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/svg.py +0 -0
  30. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/toaster.py +0 -0
  31. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/xtend.py +0 -0
  32. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/fasthtml/xtend.pyi +0 -0
  33. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/pyproject.toml +0 -0
  34. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/SOURCES.txt +0 -0
  35. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/dependency_links.txt +0 -0
  36. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/entry_points.txt +0 -0
  37. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/not-zip-safe +0 -0
  38. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/requires.txt +0 -0
  39. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/python_fasthtml.egg-info/top_level.txt +0 -0
  40. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/setup.cfg +0 -0
  41. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/setup.py +0 -0
  42. {python_fasthtml-0.12.32 → python_fasthtml-0.12.34}/tests/test_toaster.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fasthtml
3
- Version: 0.12.32
3
+ Version: 0.12.34
4
4
  Summary: The fastest way to create an HTML app
5
5
  Home-page: https://github.com/AnswerDotAI/fasthtml
6
6
  Author: Jeremy Howard and contributors
@@ -0,0 +1,2 @@
1
+ __version__ = "0.12.34"
2
+ from .core import *
@@ -46,6 +46,7 @@ d = { 'settings': { 'branch': 'main',
46
46
  'fasthtml.core.FastHTML._endp': ('api/core.html#fasthtml._endp', 'fasthtml/core.py'),
47
47
  'fasthtml.core.FastHTML.add_route': ('api/core.html#fasthtml.add_route', 'fasthtml/core.py'),
48
48
  'fasthtml.core.FastHTML.devtools_json': ('api/core.html#fasthtml.devtools_json', 'fasthtml/core.py'),
49
+ 'fasthtml.core.FastHTML.get_client': ('api/core.html#fasthtml.get_client', 'fasthtml/core.py'),
49
50
  'fasthtml.core.FastHTML.route': ('api/core.html#fasthtml.route', 'fasthtml/core.py'),
50
51
  'fasthtml.core.FastHTML.set_lifespan': ('api/core.html#fasthtml.set_lifespan', 'fasthtml/core.py'),
51
52
  'fasthtml.core.FastHTML.setup_ws': ('api/core.html#fasthtml.setup_ws', 'fasthtml/core.py'),
@@ -36,7 +36,7 @@ def railway_deploy(
36
36
  ):
37
37
  """Deploy a FastHTML app to Railway"""
38
38
  nm,ver = check_output("railway --version".split()).decode().split()
39
- assert nm=='railway', f'Unexpected railway version string: {nm}'
39
+ assert nm.startswith('railway'), f'Unexpected railway version string: {nm}'
40
40
  if ver2tuple(ver)<(3,8): return print("Please update your railway CLI version to 3.8 or higher")
41
41
  cp = run("railway status --json".split(), capture_output=True)
42
42
  if not cp.returncode:
@@ -127,6 +127,7 @@ def File(fname):
127
127
  # %% ../nbs/api/01_components.ipynb
128
128
  def show(ft, *rest, iframe=False, height='auto', style=None):
129
129
  "Renders FT Components into HTML within a Jupyter notebook."
130
+ if isinstance(ft, str): ft = Safe(ft)
130
131
  if rest: ft = (ft,)+rest
131
132
  res = to_xml(ft)
132
133
  if iframe:
@@ -206,14 +207,14 @@ _re_h2x_attr_key = re.compile(r'^[A-Za-z_-][\w-]*$')
206
207
  def html2ft(html, attr1st=False):
207
208
  """Convert HTML to an `ft` expression"""
208
209
  rev_map = {'class': 'cls', 'for': 'fr'}
209
-
210
+
210
211
  def _parse(elm, lvl=0, indent=4):
211
- if isinstance(elm, str): return repr(elm.strip()) if elm.strip() else ''
212
+ if isinstance(elm, str): return repr(elm.strip("\n")) if elm.strip() else ''
212
213
  if isinstance(elm, list): return '\n'.join(_parse(o, lvl) for o in elm)
213
214
  tag_name = elm.name.capitalize().replace("-", "_")
214
215
  if tag_name=='[document]': return _parse(list(elm.children), lvl)
215
216
  cts = elm.contents
216
- cs = [repr(c.strip()) if isinstance(c, str) else _parse(c, lvl+1)
217
+ cs = [repr(c.strip("\n")) if isinstance(c, str) else _parse(c, lvl+1)
217
218
  for c in cts if str(c).strip()]
218
219
  attrs, exotic_attrs = [], {}
219
220
  for key, value in sorted(elm.attrs.items(), key=lambda x: x[0]=='class'):
@@ -12,7 +12,7 @@ __all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc',
12
12
  'unqid']
13
13
 
14
14
  # %% ../nbs/api/00_core.ipynb
15
- import json,uuid,inspect,types,signal,asyncio,threading,inspect,random,contextlib
15
+ import json,uuid,inspect,types,signal,asyncio,threading,inspect,random,contextlib,httpx,itsdangerous
16
16
 
17
17
  from fastcore.utils import *
18
18
  from fastcore.xml import *
@@ -30,7 +30,6 @@ from urllib.parse import urlencode, parse_qs, quote, unquote
30
30
  from copy import copy,deepcopy
31
31
  from warnings import warn
32
32
  from dateutil import parser as dtparse
33
- from httpx import ASGITransport, AsyncClient
34
33
  from anyio import from_thread
35
34
  from uuid import uuid4, UUID
36
35
  from base64 import b85encode,b64encode
@@ -449,8 +448,8 @@ def _resp(req, resp, cls=empty, status_code=200):
449
448
  if cls in (Any,FT): cls=empty
450
449
  if isinstance(resp, FileResponse) and not os.path.exists(resp.path): raise HTTPException(404, resp.path)
451
450
  resp,kw = _part_resp(req, resp)
452
- if cls is not empty: return cls(resp, status_code=status_code, **kw)
453
451
  if isinstance(resp, Response): return resp
452
+ if cls is not empty: return cls(resp, status_code=status_code, **kw)
454
453
  if _is_ft_resp(resp):
455
454
  cts = _xt_cts(req, resp)
456
455
  return HTMLResponse(cts, status_code=status_code, **kw)
@@ -566,7 +565,7 @@ class FastHTML(Starlette):
566
565
  same_site='lax', sess_https_only=False, sess_domain=None, key_fname='.sesskey',
567
566
  body_wrap=noop_body, htmlkw=None, nb_hdrs=False, canonical=True, **bodykw):
568
567
  middleware,before,after = map(_list, (middleware,before,after))
569
- self.title,self.canonical = title,canonical
568
+ self.title,self.canonical,self.session_cookie,self.key_fname = title,canonical,session_cookie,key_fname
570
569
  hdrs,ftrs,exts = map(listify, (hdrs,ftrs,exts))
571
570
  exts = {k:htmx_exts[k] for k in exts}
572
571
  htmlkw = htmlkw or {}
@@ -580,9 +579,9 @@ class FastHTML(Starlette):
580
579
  on_startup,on_shutdown = listify(on_startup) or None,listify(on_shutdown) or None
581
580
  self.lifespan,self.hdrs,self.ftrs = lifespan,hdrs,ftrs
582
581
  self.body_wrap,self.before,self.after,self.htmlkw,self.bodykw = body_wrap,before,after,htmlkw,bodykw
583
- secret_key = get_key(secret_key, key_fname)
582
+ self.secret_key = get_key(secret_key, key_fname)
584
583
  if sess_cls:
585
- sess = Middleware(sess_cls, secret_key=secret_key,session_cookie=session_cookie,
584
+ sess = Middleware(sess_cls, secret_key=self.secret_key,session_cookie=session_cookie,
586
585
  max_age=max_age, path=sess_path, same_site=same_site,
587
586
  https_only=sess_https_only, domain=sess_domain)
588
587
  middleware.append(sess)
@@ -727,7 +726,7 @@ def serve(
727
726
  class Client:
728
727
  "A simple httpx ASGI client that doesn't require `async`"
729
728
  def __init__(self, app, url="http://testserver"):
730
- self.cli = AsyncClient(transport=ASGITransport(app), base_url=url)
729
+ self.cli = httpx.AsyncClient(transport=httpx.ASGITransport(app), base_url=url)
731
730
 
732
731
  def _sync(self, method, url, **kwargs):
733
732
  async def _request(): return await self.cli.request(method, url, **kwargs)
@@ -894,3 +893,14 @@ def devtools_json(self:FastHTML, path=None, uuid=None):
894
893
  @self.route(devtools_loc)
895
894
  def devtools():
896
895
  return dict(workspace=dict(root=path, uuid=uuid))
896
+
897
+ # %% ../nbs/api/00_core.ipynb
898
+ @patch
899
+ def get_client(self:FastHTML, asink=False, **kw):
900
+ "Get an httpx client with session cookes set from `**kw`"
901
+ signer = itsdangerous.TimestampSigner(self.secret_key)
902
+ data = b64encode(dumps(kw).encode())
903
+ data = signer.sign(data)
904
+ client = httpx.AsyncClient() if asink else httpx.Client()
905
+ client.cookies.update({self.session_cookie: data.decode()})
906
+ return client
@@ -62,9 +62,12 @@ def show(*s, **kwargs):
62
62
  return _show(*s, **kwargs)
63
63
 
64
64
  # %% ../nbs/api/06_jupyter.ipynb
65
- def render_ft():
65
+ def render_ft(**kw):
66
+ "Call once in a notebook or solveit dialog to auto-render components"
66
67
  @patch
67
- def _repr_markdown_(self:FT): return to_xml(Div(self, Script('if (window.htmx) htmx.process(document.body)')))
68
+ def _repr_markdown_(self:FT):
69
+ scr_proc = Script('if (window.htmx) htmx.process(document.body)')
70
+ return to_xml(Div(self, scr_proc, **kw))
68
71
 
69
72
  # %% ../nbs/api/06_jupyter.ipynb
70
73
  def htmx_config_port(port=8000):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-fasthtml
3
- Version: 0.12.32
3
+ Version: 0.12.34
4
4
  Summary: The fastest way to create an HTML app
5
5
  Home-page: https://github.com/AnswerDotAI/fasthtml
6
6
  Author: Jeremy Howard and contributors
@@ -1,7 +1,7 @@
1
1
  [DEFAULT]
2
2
  repo = fasthtml
3
3
  lib_name = python-fasthtml
4
- version = 0.12.32
4
+ version = 0.12.34
5
5
  min_python = 3.10
6
6
  license = apache2
7
7
  requirements = fastcore>=1.8.1 python-dateutil starlette>0.33 oauthlib itsdangerous uvicorn[standard]>=0.30 httpx fastlite>=0.1.1 python-multipart beautifulsoup4
@@ -1,2 +0,0 @@
1
- __version__ = "0.12.32"
2
- from .core import *