python-fasthtml 0.14.4__tar.gz → 0.14.6__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.14.6/PKG-INFO +161 -0
  2. python_fasthtml-0.14.6/README.md +126 -0
  3. python_fasthtml-0.14.6/fasthtml/__init__.py +2 -0
  4. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/_modidx.py +9 -2
  5. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/components.py +2 -6
  6. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/core.py +59 -8
  7. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/js.py +1 -1
  8. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/jupyter.py +1 -1
  9. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/oauth.py +1 -1
  10. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/pico.py +1 -1
  11. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/stripe_otp.py +1 -1
  12. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/svg.py +1 -1
  13. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/xtend.py +1 -1
  14. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/pyproject.toml +7 -2
  15. python_fasthtml-0.14.6/python_fasthtml.egg-info/PKG-INFO +161 -0
  16. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/python_fasthtml.egg-info/requires.txt +2 -2
  17. python_fasthtml-0.14.4/PKG-INFO +0 -238
  18. python_fasthtml-0.14.4/README.md +0 -203
  19. python_fasthtml-0.14.4/fasthtml/__init__.py +0 -2
  20. python_fasthtml-0.14.4/python_fasthtml.egg-info/PKG-INFO +0 -238
  21. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/CONTRIBUTING.md +0 -0
  22. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/LICENSE +0 -0
  23. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/MANIFEST.in +0 -0
  24. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/authmw.py +0 -0
  25. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/basics.py +0 -0
  26. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/cli.py +0 -0
  27. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/common.py +0 -0
  28. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/components.pyi +0 -0
  29. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/core.pyi +0 -0
  30. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/fastapp.py +0 -0
  31. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/ft.py +0 -0
  32. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/katex.js +0 -0
  33. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/live_reload.py +0 -0
  34. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/starlette.py +0 -0
  35. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/toaster.py +0 -0
  36. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/fasthtml/xtend.pyi +0 -0
  37. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/python_fasthtml.egg-info/SOURCES.txt +0 -0
  38. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/python_fasthtml.egg-info/dependency_links.txt +0 -0
  39. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/python_fasthtml.egg-info/entry_points.txt +0 -0
  40. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/python_fasthtml.egg-info/top_level.txt +0 -0
  41. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/setup.cfg +0 -0
  42. {python_fasthtml-0.14.4 → python_fasthtml-0.14.6}/tests/test_toaster.py +0 -0
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-fasthtml
3
+ Version: 0.14.6
4
+ Summary: The fastest way to create an HTML app
5
+ Author-email: Jeremy Howard and contributors <github@jhoward.fastmail.fm>
6
+ License: Apache-2.0
7
+ Project-URL: Repository, https://github.com/AnswerDotAI/fasthtml
8
+ Project-URL: Documentation, https://www.fastht.ml/docs/
9
+ Keywords: nbdev,jupyter,notebook,python
10
+ Classifier: Natural Language :: English
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: fastcore>=2.0.4
19
+ Requires-Dist: python-dateutil
20
+ Requires-Dist: starlette>=1.0.1
21
+ Requires-Dist: oauthlib
22
+ Requires-Dist: itsdangerous
23
+ Requires-Dist: uvicorn[standard]>=0.30
24
+ Requires-Dist: httpx2
25
+ Requires-Dist: fastlite>=0.1.1
26
+ Requires-Dist: python-multipart
27
+ Requires-Dist: beautifulsoup4
28
+ Provides-Extra: dev
29
+ Requires-Dist: ipython; extra == "dev"
30
+ Requires-Dist: lxml; extra == "dev"
31
+ Requires-Dist: pysym2md>=0.0.6; extra == "dev"
32
+ Requires-Dist: monsterui; extra == "dev"
33
+ Requires-Dist: PyJWT; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # FastHTML
37
+
38
+
39
+ <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
40
+
41
+ Welcome to the official FastHTML documentation.
42
+
43
+ FastHTML is a new next-generation web framework for fast, scalable web applications with minimal, compact code. It’s designed to be:
44
+
45
+ - Powerful and expressive enough to build the most advanced, interactive web apps you can imagine.
46
+ - Fast and lightweight, so you can write less code and get more done.
47
+ - Easy to learn and use, with a simple, intuitive syntax that makes it easy to build complex apps quickly.
48
+
49
+ FastHTML apps are just Python code, so you can use FastHTML with the full power of the Python language and ecosystem. FastHTML’s functionality maps 1:1 directly to HTML and HTTP, but allows them to be encapsulated using good software engineering practices—so you’ll need to understand these foundations to use this library fully. To understand how and why this works, please read this first: [fastht.ml/about](https://fastht.ml/about).
50
+
51
+ ## Installation
52
+
53
+ Since `fasthtml` is a Python library, you can install it with:
54
+
55
+ ``` sh
56
+ pip install python-fasthtml
57
+ ```
58
+
59
+ In the near future, we hope to add component libraries that can likewise be installed via `pip`.
60
+
61
+ ## Usage
62
+
63
+ For a minimal app, create a file “main.py” as follows:
64
+
65
+ <div class="code-with-filename">
66
+
67
+ **main.py**
68
+
69
+ ``` python
70
+ from fasthtml.common import *
71
+
72
+ app,rt = fast_app()
73
+
74
+ @rt('/')
75
+ def get(): return Div(P('Hello World!'), hx_get="/change")
76
+
77
+ serve()
78
+ ```
79
+
80
+ </div>
81
+
82
+ Running the app with `python main.py` prints out a link to your running app: `http://localhost:5001`. Visit that link in your browser and you should see a page with the text “Hello World!”. Congratulations, you’ve just created your first FastHTML app!
83
+
84
+ Adding interactivity is surprisingly easy, thanks to HTMX. Modify the file to add this function:
85
+
86
+ <div class="code-with-filename">
87
+
88
+ **main.py**
89
+
90
+ ``` python
91
+ @rt('/change')
92
+ def get(): return P('Nice to be here!')
93
+ ```
94
+
95
+ </div>
96
+
97
+ You now have a page with a clickable element that changes the text when clicked. When clicking on this link, the server will respond with an “HTML partial”—that is, just a snippet of HTML which will be inserted into the existing page. In this case, the returned element will replace the original P element (since that’s the default behavior of HTMX) with the new version returned by the second route.
98
+
99
+ This “hypermedia-based” approach to web development is a powerful way to build web applications.
100
+
101
+ ### Getting help from AI
102
+
103
+ Because FastHTML is newer than most LLMs, AI systems like Cursor, ChatGPT, Claude, and Copilot won’t give useful answers about it. To fix that problem, we’ve provided an LLM-friendly guide that teaches them how to use FastHTML. To use it, add this link for your AI helper to use:
104
+
105
+ - [/llms-ctx.txt](https://www.fastht.ml/docs/llms-ctx.txt)
106
+
107
+ This example is in a format based on recommendations from Anthropic for use with [Claude Projects](https://support.anthropic.com/en/articles/9517075-what-are-projects). This works so well that we’ve actually found that Claude can provide even better information than our own documentation! For instance, read through [this annotated Claude chat](https://gist.github.com/jph00/9559b0a563f6a370029bec1d1cc97b74) for some great getting-started information, entirely generated from a project using the above text file as context.
108
+
109
+ If you use Cursor, type `@doc` then choose “*Add new doc*”, and use the /llms-ctx.txt link above. The context file is auto-generated from our [`llms.txt`](https://llmstxt.org/) (our proposed standard for providing AI-friendly information)—you can generate alternative versions suitable for other models as needed.
110
+
111
+ ## Next Steps
112
+
113
+ Start with the official sources to learn more about FastHTML:
114
+
115
+ - [About](https://fastht.ml/about): Learn about the core ideas behind FastHTML
116
+ - [Documentation](https://www.fastht.ml/docs): Learn from examples how to write FastHTML code
117
+ - [Idiomatic app](https://github.com/AnswerDotAI/fasthtml/blob/main/examples/adv_app.py): Heavily commented source code walking through a complete application, including custom authentication, JS library connections, and database use.
118
+
119
+ We also have a 1-hour intro video:
120
+
121
+ <https://www.youtube.com/embed/Auqrm7WFc0I>
122
+
123
+ The capabilities of FastHTML are vast and growing, and not all the features and patterns have been documented yet. Be prepared to invest time into studying and modifying source code, such as the main FastHTML repo’s notebooks and the official FastHTML examples repo:
124
+
125
+ - [FastHTML Examples Repo on GitHub](https://github.com/AnswerDotAI/fasthtml-example)
126
+ - [FastHTML Repo on GitHub](https://github.com/AnswerDotAI/fasthtml)
127
+
128
+ Then explore the small but growing third-party ecosystem of FastHTML tutorials, notebooks, libraries, and components:
129
+
130
+ - [FastHTML Gallery](https://gallery.fastht.ml): Learn from minimal examples of components (ie chat bubbles, click-to-edit, infinite scroll, etc)
131
+ - [Creating Custom FastHTML Tags for Markdown Rendering](https://isaac-flath.github.io/website/posts/boots/FasthtmlTutorial.html) by Isaac Flath
132
+ - [How to Build a Simple Login System in FastHTML](https://blog.mariusvach.com/posts/login-fasthtml) by Marius Vach
133
+ - Your tutorial here!
134
+
135
+ Finally, join the FastHTML community to ask questions, share your work, and learn from others:
136
+
137
+ - [Discord](https://discord.gg/qcXvcxMhdP)
138
+
139
+ ## Other languages and related projects
140
+
141
+ If you’re not a Python user, or are keen to try out a new language, we’ll list here other projects that have a similar approach to FastHTML. (Please reach out if you know of any other projects that you’d like to see added.)
142
+
143
+ - [htmgo](https://htmgo.dev/) (Go): “*htmgo is a lightweight pure go way to build interactive websites / web applications using go & htmx. By combining the speed & simplicity of go + hypermedia attributes (htmx) to add interactivity to websites, all conveniently wrapped in pure go, you can build simple, fast, interactive websites without touching javascript. All compiled to a single deployable binary*”
144
+
145
+ If you’re just interested in functional HTML components, rather than a full HTMX server solution, consider:
146
+
147
+ - [fastcore.xml.FT](https://fastcore.fast.ai/xml.html): This is actually what FastHTML uses behind the scenes
148
+ - [htpy](https://htpy.dev/): Similar to [`fastcore.xml.FT`](https://fastcore.fast.ai/xml.html#ft), but with a somewhat different syntax
149
+ - [elm-html](https://package.elm-lang.org/packages/elm/html/latest/): Elm’s built-in HTML library with a type-safe functional approach
150
+ - [hiccup](https://github.com/weavejester/hiccup): Popular library for representing HTML in Clojure using vectors
151
+ - [hiccl](https://github.com/garlic0x1/hiccl): HTML generation library for Common Lisp inspired by Clojure’s Hiccup
152
+ - [Falco.Markup](https://github.com/pimbrouwers/Falco): F# HTML DSL and web framework with type-safe HTML generation
153
+ - [Lucid](https://github.com/chrisdone/lucid): Type-safe HTML generation for Haskell using monad transformers
154
+ - [dream-html](https://github.com/aantron/dream): Part of the Dream web framework for OCaml, provides type-safe HTML templating
155
+
156
+ For other hypermedia application platforms, not based on HTMX, take a look at:
157
+
158
+ - [Hotwire/Turbo](https://turbo.hotwired.dev/): Rails-oriented framework that similarly uses HTML-over-the-wire
159
+ - [LiveView](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html): Phoenix framework’s solution for building interactive web apps with minimal JavaScript
160
+ - [Unpoly](https://unpoly.com/): Another HTML-over-the-wire framework with progressive enhancement
161
+ - [Livewire](https://laravel-livewire.com/): Laravel’s take on building dynamic interfaces with minimal JavaScript
@@ -0,0 +1,126 @@
1
+ # FastHTML
2
+
3
+
4
+ <!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
5
+
6
+ Welcome to the official FastHTML documentation.
7
+
8
+ FastHTML is a new next-generation web framework for fast, scalable web applications with minimal, compact code. It’s designed to be:
9
+
10
+ - Powerful and expressive enough to build the most advanced, interactive web apps you can imagine.
11
+ - Fast and lightweight, so you can write less code and get more done.
12
+ - Easy to learn and use, with a simple, intuitive syntax that makes it easy to build complex apps quickly.
13
+
14
+ FastHTML apps are just Python code, so you can use FastHTML with the full power of the Python language and ecosystem. FastHTML’s functionality maps 1:1 directly to HTML and HTTP, but allows them to be encapsulated using good software engineering practices—so you’ll need to understand these foundations to use this library fully. To understand how and why this works, please read this first: [fastht.ml/about](https://fastht.ml/about).
15
+
16
+ ## Installation
17
+
18
+ Since `fasthtml` is a Python library, you can install it with:
19
+
20
+ ``` sh
21
+ pip install python-fasthtml
22
+ ```
23
+
24
+ In the near future, we hope to add component libraries that can likewise be installed via `pip`.
25
+
26
+ ## Usage
27
+
28
+ For a minimal app, create a file “main.py” as follows:
29
+
30
+ <div class="code-with-filename">
31
+
32
+ **main.py**
33
+
34
+ ``` python
35
+ from fasthtml.common import *
36
+
37
+ app,rt = fast_app()
38
+
39
+ @rt('/')
40
+ def get(): return Div(P('Hello World!'), hx_get="/change")
41
+
42
+ serve()
43
+ ```
44
+
45
+ </div>
46
+
47
+ Running the app with `python main.py` prints out a link to your running app: `http://localhost:5001`. Visit that link in your browser and you should see a page with the text “Hello World!”. Congratulations, you’ve just created your first FastHTML app!
48
+
49
+ Adding interactivity is surprisingly easy, thanks to HTMX. Modify the file to add this function:
50
+
51
+ <div class="code-with-filename">
52
+
53
+ **main.py**
54
+
55
+ ``` python
56
+ @rt('/change')
57
+ def get(): return P('Nice to be here!')
58
+ ```
59
+
60
+ </div>
61
+
62
+ You now have a page with a clickable element that changes the text when clicked. When clicking on this link, the server will respond with an “HTML partial”—that is, just a snippet of HTML which will be inserted into the existing page. In this case, the returned element will replace the original P element (since that’s the default behavior of HTMX) with the new version returned by the second route.
63
+
64
+ This “hypermedia-based” approach to web development is a powerful way to build web applications.
65
+
66
+ ### Getting help from AI
67
+
68
+ Because FastHTML is newer than most LLMs, AI systems like Cursor, ChatGPT, Claude, and Copilot won’t give useful answers about it. To fix that problem, we’ve provided an LLM-friendly guide that teaches them how to use FastHTML. To use it, add this link for your AI helper to use:
69
+
70
+ - [/llms-ctx.txt](https://www.fastht.ml/docs/llms-ctx.txt)
71
+
72
+ This example is in a format based on recommendations from Anthropic for use with [Claude Projects](https://support.anthropic.com/en/articles/9517075-what-are-projects). This works so well that we’ve actually found that Claude can provide even better information than our own documentation! For instance, read through [this annotated Claude chat](https://gist.github.com/jph00/9559b0a563f6a370029bec1d1cc97b74) for some great getting-started information, entirely generated from a project using the above text file as context.
73
+
74
+ If you use Cursor, type `@doc` then choose “*Add new doc*”, and use the /llms-ctx.txt link above. The context file is auto-generated from our [`llms.txt`](https://llmstxt.org/) (our proposed standard for providing AI-friendly information)—you can generate alternative versions suitable for other models as needed.
75
+
76
+ ## Next Steps
77
+
78
+ Start with the official sources to learn more about FastHTML:
79
+
80
+ - [About](https://fastht.ml/about): Learn about the core ideas behind FastHTML
81
+ - [Documentation](https://www.fastht.ml/docs): Learn from examples how to write FastHTML code
82
+ - [Idiomatic app](https://github.com/AnswerDotAI/fasthtml/blob/main/examples/adv_app.py): Heavily commented source code walking through a complete application, including custom authentication, JS library connections, and database use.
83
+
84
+ We also have a 1-hour intro video:
85
+
86
+ <https://www.youtube.com/embed/Auqrm7WFc0I>
87
+
88
+ The capabilities of FastHTML are vast and growing, and not all the features and patterns have been documented yet. Be prepared to invest time into studying and modifying source code, such as the main FastHTML repo’s notebooks and the official FastHTML examples repo:
89
+
90
+ - [FastHTML Examples Repo on GitHub](https://github.com/AnswerDotAI/fasthtml-example)
91
+ - [FastHTML Repo on GitHub](https://github.com/AnswerDotAI/fasthtml)
92
+
93
+ Then explore the small but growing third-party ecosystem of FastHTML tutorials, notebooks, libraries, and components:
94
+
95
+ - [FastHTML Gallery](https://gallery.fastht.ml): Learn from minimal examples of components (ie chat bubbles, click-to-edit, infinite scroll, etc)
96
+ - [Creating Custom FastHTML Tags for Markdown Rendering](https://isaac-flath.github.io/website/posts/boots/FasthtmlTutorial.html) by Isaac Flath
97
+ - [How to Build a Simple Login System in FastHTML](https://blog.mariusvach.com/posts/login-fasthtml) by Marius Vach
98
+ - Your tutorial here!
99
+
100
+ Finally, join the FastHTML community to ask questions, share your work, and learn from others:
101
+
102
+ - [Discord](https://discord.gg/qcXvcxMhdP)
103
+
104
+ ## Other languages and related projects
105
+
106
+ If you’re not a Python user, or are keen to try out a new language, we’ll list here other projects that have a similar approach to FastHTML. (Please reach out if you know of any other projects that you’d like to see added.)
107
+
108
+ - [htmgo](https://htmgo.dev/) (Go): “*htmgo is a lightweight pure go way to build interactive websites / web applications using go & htmx. By combining the speed & simplicity of go + hypermedia attributes (htmx) to add interactivity to websites, all conveniently wrapped in pure go, you can build simple, fast, interactive websites without touching javascript. All compiled to a single deployable binary*”
109
+
110
+ If you’re just interested in functional HTML components, rather than a full HTMX server solution, consider:
111
+
112
+ - [fastcore.xml.FT](https://fastcore.fast.ai/xml.html): This is actually what FastHTML uses behind the scenes
113
+ - [htpy](https://htpy.dev/): Similar to [`fastcore.xml.FT`](https://fastcore.fast.ai/xml.html#ft), but with a somewhat different syntax
114
+ - [elm-html](https://package.elm-lang.org/packages/elm/html/latest/): Elm’s built-in HTML library with a type-safe functional approach
115
+ - [hiccup](https://github.com/weavejester/hiccup): Popular library for representing HTML in Clojure using vectors
116
+ - [hiccl](https://github.com/garlic0x1/hiccl): HTML generation library for Common Lisp inspired by Clojure’s Hiccup
117
+ - [Falco.Markup](https://github.com/pimbrouwers/Falco): F# HTML DSL and web framework with type-safe HTML generation
118
+ - [Lucid](https://github.com/chrisdone/lucid): Type-safe HTML generation for Haskell using monad transformers
119
+ - [dream-html](https://github.com/aantron/dream): Part of the Dream web framework for OCaml, provides type-safe HTML templating
120
+
121
+ For other hypermedia application platforms, not based on HTMX, take a look at:
122
+
123
+ - [Hotwire/Turbo](https://turbo.hotwired.dev/): Rails-oriented framework that similarly uses HTML-over-the-wire
124
+ - [LiveView](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html): Phoenix framework’s solution for building interactive web apps with minimal JavaScript
125
+ - [Unpoly](https://unpoly.com/): Another HTML-over-the-wire framework with progressive enhancement
126
+ - [Livewire](https://laravel-livewire.com/): Laravel’s take on building dynamic interfaces with minimal JavaScript
@@ -0,0 +1,2 @@
1
+ __version__ = "0.14.6"
2
+ from .core import *
@@ -15,7 +15,6 @@ d = { 'settings': { 'branch': 'main',
15
15
  'fasthtml.components.FT.__radd__': ('api/components.html#ft.__radd__', 'fasthtml/components.py'),
16
16
  'fasthtml.components.FT.__str__': ('api/components.html#ft.__str__', 'fasthtml/components.py'),
17
17
  'fasthtml.components.File': ('api/components.html#file', 'fasthtml/components.py'),
18
- 'fasthtml.components.__getattr__': ('api/components.html#__getattr__', 'fasthtml/components.py'),
19
18
  'fasthtml.components._fill_item': ('api/components.html#_fill_item', 'fasthtml/components.py'),
20
19
  'fasthtml.components.attrmap_x': ('api/components.html#attrmap_x', 'fasthtml/components.py'),
21
20
  'fasthtml.components.fill_dataclass': ('api/components.html#fill_dataclass', 'fasthtml/components.py'),
@@ -95,6 +94,9 @@ d = { 'settings': { 'branch': 'main',
95
94
  'fasthtml.core.RouteFuncs.__getattr__': ('api/core.html#routefuncs.__getattr__', 'fasthtml/core.py'),
96
95
  'fasthtml.core.RouteFuncs.__init__': ('api/core.html#routefuncs.__init__', 'fasthtml/core.py'),
97
96
  'fasthtml.core.RouteFuncs.__setattr__': ('api/core.html#routefuncs.__setattr__', 'fasthtml/core.py'),
97
+ 'fasthtml.core.StaticImmutable': ('api/core.html#staticimmutable', 'fasthtml/core.py'),
98
+ 'fasthtml.core.StaticImmutable.file_response': ( 'api/core.html#staticimmutable.file_response',
99
+ 'fasthtml/core.py'),
98
100
  'fasthtml.core.StaticNoCache': ('api/core.html#staticnocache', 'fasthtml/core.py'),
99
101
  'fasthtml.core.StaticNoCache.file_response': ( 'api/core.html#staticnocache.file_response',
100
102
  'fasthtml/core.py'),
@@ -131,6 +133,8 @@ d = { 'settings': { 'branch': 'main',
131
133
  'fasthtml.core._to_htmx_header': ('api/core.html#_to_htmx_header', 'fasthtml/core.py'),
132
134
  'fasthtml.core._to_xml': ('api/core.html#_to_xml', 'fasthtml/core.py'),
133
135
  'fasthtml.core._url_for': ('api/core.html#_url_for', 'fasthtml/core.py'),
136
+ 'fasthtml.core._vhash': ('api/core.html#_vhash', 'fasthtml/core.py'),
137
+ 'fasthtml.core._wait_disconnect': ('api/core.html#_wait_disconnect', 'fasthtml/core.py'),
134
138
  'fasthtml.core._wrap_call': ('api/core.html#_wrap_call', 'fasthtml/core.py'),
135
139
  'fasthtml.core._wrap_ex': ('api/core.html#_wrap_ex', 'fasthtml/core.py'),
136
140
  'fasthtml.core._wrap_req': ('api/core.html#_wrap_req', 'fasthtml/core.py'),
@@ -138,6 +142,7 @@ d = { 'settings': { 'branch': 'main',
138
142
  'fasthtml.core._ws_endp': ('api/core.html#_ws_endp', 'fasthtml/core.py'),
139
143
  'fasthtml.core._xt_cts': ('api/core.html#_xt_cts', 'fasthtml/core.py'),
140
144
  'fasthtml.core.add_sig_param': ('api/core.html#add_sig_param', 'fasthtml/core.py'),
145
+ 'fasthtml.core.cancel_on_disconnect': ('api/core.html#cancel_on_disconnect', 'fasthtml/core.py'),
141
146
  'fasthtml.core.cookie': ('api/core.html#cookie', 'fasthtml/core.py'),
142
147
  'fasthtml.core.decode_uri': ('api/core.html#decode_uri', 'fasthtml/core.py'),
143
148
  'fasthtml.core.def_hdrs': ('api/core.html#def_hdrs', 'fasthtml/core.py'),
@@ -160,7 +165,9 @@ d = { 'settings': { 'branch': 'main',
160
165
  'fasthtml.core.signal_shutdown': ('api/core.html#signal_shutdown', 'fasthtml/core.py'),
161
166
  'fasthtml.core.snake2hyphens': ('api/core.html#snake2hyphens', 'fasthtml/core.py'),
162
167
  'fasthtml.core.unqid': ('api/core.html#unqid', 'fasthtml/core.py'),
163
- 'fasthtml.core.uri': ('api/core.html#uri', 'fasthtml/core.py')},
168
+ 'fasthtml.core.until_disconnect': ('api/core.html#until_disconnect', 'fasthtml/core.py'),
169
+ 'fasthtml.core.uri': ('api/core.html#uri', 'fasthtml/core.py'),
170
+ 'fasthtml.core.vurl': ('api/core.html#vurl', 'fasthtml/core.py')},
164
171
  'fasthtml.fastapp': {},
165
172
  'fasthtml.ft': {},
166
173
  'fasthtml.js': { 'fasthtml.js.HighlightJS': ('api/js.html#highlightjs', 'fasthtml/js.py'),
@@ -1,6 +1,6 @@
1
1
  """`ft_html` and `ft_hx` functions to add some conveniences to `ft`, along with a full set of basic HTML components, and functions to work with forms and `FT` conversion
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/components.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/components.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/01_components.ipynb.
6
6
 
@@ -195,11 +195,7 @@ def find_inputs(e, tags='input', **kw):
195
195
  return inputs
196
196
 
197
197
  # %% ../nbs/api/01_components.ipynb #1d8a28b1
198
- def __getattr__(tag):
199
- if tag.startswith('_') or tag[0].islower(): raise AttributeError
200
- tag = tag.replace("_", "-")
201
- def _f(*c, target_id=None, **kwargs): return ft_hx(tag, *c, target_id=target_id, **kwargs)
202
- return _f
198
+ __getattr__ = mk_getattr(ft_hx)
203
199
 
204
200
  # %% ../nbs/api/01_components.ipynb #afb0f65c
205
201
  _re_h2x_attr_key = re.compile(r'^[A-Za-z_-][\w-]*$')
@@ -1,6 +1,6 @@
1
1
  """The `FastHTML` subclass of `Starlette`.
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/core.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/core.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/00_core.ipynb.
6
6
 
@@ -10,15 +10,17 @@ __all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'DEF_MAXPART', 'htmx_ex
10
10
  'snake2hyphens', 'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', 'ApiReturn',
11
11
  'JSONResponse', 'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'uri', 'decode_uri', 'flat_tuple',
12
12
  'noop_body', 'respond', 'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'Lifespan', 'FastHTML',
13
- 'HostRoute', 'nested_name', 'serve', 'Client', 'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param',
14
- 'StaticNoCache', 'add_sig_param', 'into', 'MiddlewareBase', 'FtResponse', 'unqid']
13
+ 'HostRoute', 'nested_name', 'serve', 'until_disconnect', 'cancel_on_disconnect', 'Client', 'RouteFuncs',
14
+ 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', 'StaticImmutable', 'vurl', 'add_sig_param', 'into',
15
+ 'MiddlewareBase', 'FtResponse', 'unqid']
15
16
 
16
17
  # %% ../nbs/api/00_core.ipynb #23503b9e
17
- import json,uuid,inspect,types,asyncio,inspect,random,contextlib,itsdangerous
18
+ import json,uuid,inspect,types,asyncio,inspect,random,contextlib,itsdangerous,hashlib
19
+ from uuid import uuid5, NAMESPACE_URL
18
20
 
19
21
  from fastcore.utils import *
20
22
  from fastcore.xml import *
21
- from fastcore.meta import use_kwargs_dict,delegates
23
+ from fastcore.meta import use_kwargs_dict,delegates,splice_sig
22
24
  from fastcore.style import S
23
25
 
24
26
  from types import UnionType, SimpleNamespace as ns, GenericAlias
@@ -28,7 +30,7 @@ from dataclasses import dataclass
28
30
  from inspect import Parameter,get_annotations
29
31
  from functools import partialmethod, update_wrapper
30
32
  from http import cookies
31
- from urllib.parse import urlencode, parse_qs, quote, unquote
33
+ from urllib.parse import urlencode, parse_qs, quote, unquote, urlsplit, urlunsplit
32
34
  from copy import deepcopy
33
35
  from warnings import warn
34
36
  from dateutil import parser as dtparse
@@ -819,6 +821,35 @@ def serve(
819
821
  print('Link: '+ S.light_red.bold(link))
820
822
  run(f'{appname}:{app}', host=host, port=port, reload=reload, **kwargs)
821
823
 
824
+ # %% ../nbs/api/00_core.ipynb #c5220a0e
825
+ async def _wait_disconnect(req):
826
+ while (await req.receive())["type"] != "http.disconnect": pass
827
+
828
+ async def until_disconnect(req, coro):
829
+ "Await `coro`, cancelling it (and returning an empty response) if the client disconnects first"
830
+ work,watch = asyncio.ensure_future(coro),asyncio.ensure_future(_wait_disconnect(req))
831
+ try:
832
+ done,_ = await asyncio.wait({work,watch}, return_when=asyncio.FIRST_COMPLETED)
833
+ if work in done: return work.result()
834
+ return Response(status_code=204)
835
+ finally:
836
+ watch.cancel()
837
+ if not work.done(): work.cancel()
838
+
839
+ # %% ../nbs/api/00_core.ipynb #c5721d76
840
+ def cancel_on_disconnect(
841
+ f=None, # Async route handler to wrap
842
+ *,
843
+ timeout=None, # Also cancel the handler after this many seconds
844
+ ):
845
+ "Route decorator: cancel the handler when the client disconnects"
846
+ if f is None: return partial(cancel_on_disconnect, timeout=timeout)
847
+ assert is_async_callable(f), "cancel_on_disconnect requires an async handler"
848
+ async def _f(__req: Request, *args, **kw):
849
+ c = until_disconnect(__req, f(**kw))
850
+ return await (asyncio.wait_for(c, timeout) if timeout is not None else c)
851
+ return splice_sig(_f, f)
852
+
822
853
  # %% ../nbs/api/00_core.ipynb #8121968a
823
854
  class Client:
824
855
  "A simple httpx ASGI client that doesn't require `async`"
@@ -934,6 +965,26 @@ class StaticNoCache(StaticFiles):
934
965
  resp.headers.setdefault("Cache-Control", "no-cache")
935
966
  return resp
936
967
 
968
+ # %% ../nbs/api/00_core.ipynb #74801f94
969
+ class StaticImmutable(StaticFiles):
970
+ "Like `StaticNoCache`, but marks responses as cacheable forever: for versioned URLs such as `vurl` links or content-hashed filenames"
971
+ def file_response(self, *args, **kwargs):
972
+ resp = super().file_response(*args, **kwargs)
973
+ resp.headers.setdefault("Cache-Control", "public, max-age=31536000, immutable")
974
+ return resp
975
+
976
+ # %% ../nbs/api/00_core.ipynb #e38fd6c7
977
+ @flexicache(mtime_policy(arg=0))
978
+ def _vhash(p): return hashlib.blake2b(p.read_bytes(), digest_size=4).hexdigest()
979
+
980
+ def vurl(path, root='.'):
981
+ "Return `path` as a URL with a `v` query param hashing the file's contents, so the URL changes when the file does"
982
+ u = urlsplit(str(path))
983
+ p = Path(root)/u.path.lstrip('/')
984
+ q = f'{u.query}&' if u.query else ''
985
+ return urlunsplit(u._replace(query=f'{q}v={_vhash(p)}'))
986
+
987
+
937
988
  # %% ../nbs/api/00_core.ipynb #7189daf8
938
989
  from functools import wraps
939
990
  from inspect import signature, isawaitable
@@ -1024,10 +1075,10 @@ devtools_loc = "/.well-known/appspecific/com.chrome.devtools.json"
1024
1075
  @patch
1025
1076
  def devtools_json(self:FastHTML, path=None, uuid=None):
1026
1077
  if not path: path = Path().absolute()
1027
- if not uuid: uuid = get_key()
1078
+ if not uuid: uuid = str(uuid5(NAMESPACE_URL, str(path)))
1028
1079
  @self.route(devtools_loc)
1029
1080
  def devtools():
1030
- return dict(workspace=dict(root=path, uuid=uuid))
1081
+ return dict(workspace=dict(root=str(path), uuid=uuid))
1031
1082
 
1032
1083
  # %% ../nbs/api/00_core.ipynb #e27908c0
1033
1084
  @patch
@@ -1,6 +1,6 @@
1
1
  """Basic external Javascript lib wrappers
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/js.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/js.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/03_js.ipynb.
6
6
 
@@ -1,6 +1,6 @@
1
1
  """Use FastHTML in Jupyter notebooks
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/jupyter.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/jupyter.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/06_jupyter.ipynb.
6
6
 
@@ -1,6 +1,6 @@
1
1
  """Basic scaffolding for handling OAuth
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/oauth.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/oauth.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/08_oauth.ipynb.
6
6
 
@@ -1,6 +1,6 @@
1
1
  """Basic components for generating Pico CSS tags
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/pico.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/pico.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/04_pico.ipynb.
6
6
 
@@ -1,4 +1,4 @@
1
- """Docs: https://www.fastht.ml/docsexplains/stripe.html.md"""
1
+ """Docs: https://www.fastht.ml/docs/explains/stripe.html.md"""
2
2
 
3
3
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/explains/Stripe.ipynb.
4
4
 
@@ -1,6 +1,6 @@
1
1
  """Simple SVG FT elements
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/svg.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/svg.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/05_svg.ipynb.
6
6
 
@@ -1,6 +1,6 @@
1
1
  """Simple extensions to standard HTML components, such as adding sensible defaults
2
2
 
3
- Docs: https://www.fastht.ml/docsapi/xtend.html.md"""
3
+ Docs: https://www.fastht.ml/docs/api/xtend.html.md"""
4
4
 
5
5
  # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/02_xtend.ipynb.
6
6
 
@@ -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.45', 'python-dateutil', 'starlette>=1.0.1', 'oauthlib', 'itsdangerous', 'uvicorn[standard]>=0.30', 'httpx2', 'fastlite>=0.1.1', 'python-multipart', 'beautifulsoup4']
15
+ dependencies = ['fastcore>=2.0.4', 'python-dateutil', 'starlette>=1.0.1', 'oauthlib', 'itsdangerous', 'uvicorn[standard]>=0.30', 'httpx2', 'fastlite>=0.1.1', 'python-multipart', 'beautifulsoup4']
16
16
 
17
17
  [project.urls]
18
18
  Repository = "https://github.com/AnswerDotAI/fasthtml"
@@ -22,7 +22,7 @@ Documentation = "https://www.fastht.ml/docs/"
22
22
  fasthtml = "fasthtml._modidx:d"
23
23
 
24
24
  [project.optional-dependencies]
25
- dev = ['ipython', 'lxml', 'pysymbol_llm', 'monsterui', 'PyJWT']
25
+ dev = ['ipython', 'lxml', 'pysym2md>=0.0.6', 'monsterui', 'PyJWT']
26
26
 
27
27
 
28
28
  [project.scripts]
@@ -41,3 +41,8 @@ allowed_cell_metadata_keys = ['solveit_ai']
41
41
  jupyter_hooks = true
42
42
  custom_sidebar = false
43
43
  lib_path = "fasthtml"
44
+
45
+ [tool.chkstyle]
46
+ skip_paths = ["_modidx.py"]
47
+ ignore = ["closing-bracket", "inefficient-multiline-signature", "inefficient-multiline-expression"]
48
+