python-fasthtml 0.14.5__tar.gz → 0.14.7__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.14.7/PKG-INFO +161 -0
- python_fasthtml-0.14.7/README.md +126 -0
- python_fasthtml-0.14.7/fasthtml/__init__.py +2 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/_modidx.py +6 -4
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/core.py +27 -6
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/jupyter.py +3 -30
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/pyproject.toml +4 -2
- python_fasthtml-0.14.7/python_fasthtml.egg-info/PKG-INFO +161 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/python_fasthtml.egg-info/requires.txt +2 -2
- python_fasthtml-0.14.5/PKG-INFO +0 -238
- python_fasthtml-0.14.5/README.md +0 -203
- python_fasthtml-0.14.5/fasthtml/__init__.py +0 -2
- python_fasthtml-0.14.5/python_fasthtml.egg-info/PKG-INFO +0 -238
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/CONTRIBUTING.md +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/LICENSE +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/MANIFEST.in +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/authmw.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/basics.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/cli.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/common.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/components.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/components.pyi +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/core.pyi +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/fastapp.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/ft.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/js.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/katex.js +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/live_reload.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/oauth.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/pico.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/starlette.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/stripe_otp.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/svg.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/toaster.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/xtend.py +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/fasthtml/xtend.pyi +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/python_fasthtml.egg-info/SOURCES.txt +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/python_fasthtml.egg-info/dependency_links.txt +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/python_fasthtml.egg-info/entry_points.txt +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/python_fasthtml.egg-info/top_level.txt +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/setup.cfg +0 -0
- {python_fasthtml-0.14.5 → python_fasthtml-0.14.7}/tests/test_toaster.py +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-fasthtml
|
|
3
|
+
Version: 0.14.7
|
|
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.1.2
|
|
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
|
|
@@ -94,6 +94,9 @@ d = { 'settings': { 'branch': 'main',
|
|
|
94
94
|
'fasthtml.core.RouteFuncs.__getattr__': ('api/core.html#routefuncs.__getattr__', 'fasthtml/core.py'),
|
|
95
95
|
'fasthtml.core.RouteFuncs.__init__': ('api/core.html#routefuncs.__init__', 'fasthtml/core.py'),
|
|
96
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'),
|
|
97
100
|
'fasthtml.core.StaticNoCache': ('api/core.html#staticnocache', 'fasthtml/core.py'),
|
|
98
101
|
'fasthtml.core.StaticNoCache.file_response': ( 'api/core.html#staticnocache.file_response',
|
|
99
102
|
'fasthtml/core.py'),
|
|
@@ -130,6 +133,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
130
133
|
'fasthtml.core._to_htmx_header': ('api/core.html#_to_htmx_header', 'fasthtml/core.py'),
|
|
131
134
|
'fasthtml.core._to_xml': ('api/core.html#_to_xml', 'fasthtml/core.py'),
|
|
132
135
|
'fasthtml.core._url_for': ('api/core.html#_url_for', 'fasthtml/core.py'),
|
|
136
|
+
'fasthtml.core._vhash': ('api/core.html#_vhash', 'fasthtml/core.py'),
|
|
133
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'),
|
|
@@ -162,7 +166,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
162
166
|
'fasthtml.core.snake2hyphens': ('api/core.html#snake2hyphens', 'fasthtml/core.py'),
|
|
163
167
|
'fasthtml.core.unqid': ('api/core.html#unqid', 'fasthtml/core.py'),
|
|
164
168
|
'fasthtml.core.until_disconnect': ('api/core.html#until_disconnect', 'fasthtml/core.py'),
|
|
165
|
-
'fasthtml.core.uri': ('api/core.html#uri', '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')},
|
|
166
171
|
'fasthtml.fastapp': {},
|
|
167
172
|
'fasthtml.ft': {},
|
|
168
173
|
'fasthtml.js': { 'fasthtml.js.HighlightJS': ('api/js.html#highlightjs', 'fasthtml/js.py'),
|
|
@@ -185,13 +190,10 @@ d = { 'settings': { 'branch': 'main',
|
|
|
185
190
|
'fasthtml.jupyter.JupyUviAsync.start': ('api/jupyter.html#jupyuviasync.start', 'fasthtml/jupyter.py'),
|
|
186
191
|
'fasthtml.jupyter.JupyUviAsync.stop': ('api/jupyter.html#jupyuviasync.stop', 'fasthtml/jupyter.py'),
|
|
187
192
|
'fasthtml.jupyter.htmx_config_port': ('api/jupyter.html#htmx_config_port', 'fasthtml/jupyter.py'),
|
|
188
|
-
'fasthtml.jupyter.is_port_free': ('api/jupyter.html#is_port_free', 'fasthtml/jupyter.py'),
|
|
189
193
|
'fasthtml.jupyter.nb_serve': ('api/jupyter.html#nb_serve', 'fasthtml/jupyter.py'),
|
|
190
194
|
'fasthtml.jupyter.nb_serve_async': ('api/jupyter.html#nb_serve_async', 'fasthtml/jupyter.py'),
|
|
191
195
|
'fasthtml.jupyter.render_ft': ('api/jupyter.html#render_ft', 'fasthtml/jupyter.py'),
|
|
192
196
|
'fasthtml.jupyter.show': ('api/jupyter.html#show', 'fasthtml/jupyter.py'),
|
|
193
|
-
'fasthtml.jupyter.wait_port_free': ('api/jupyter.html#wait_port_free', 'fasthtml/jupyter.py'),
|
|
194
|
-
'fasthtml.jupyter.wait_port_free_async': ('api/jupyter.html#wait_port_free_async', 'fasthtml/jupyter.py'),
|
|
195
197
|
'fasthtml.jupyter.ws_client': ('api/jupyter.html#ws_client', 'fasthtml/jupyter.py')},
|
|
196
198
|
'fasthtml.live_reload': {},
|
|
197
199
|
'fasthtml.oauth': { 'fasthtml.oauth.AppleAppClient': ('api/oauth.html#appleappclient', 'fasthtml/oauth.py'),
|
|
@@ -11,11 +11,12 @@ __all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'DEF_MAXPART', 'htmx_ex
|
|
|
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
13
|
'HostRoute', 'nested_name', 'serve', 'until_disconnect', 'cancel_on_disconnect', 'Client', 'RouteFuncs',
|
|
14
|
-
'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', '
|
|
15
|
-
'FtResponse', 'unqid']
|
|
14
|
+
'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', 'StaticImmutable', 'vurl', 'add_sig_param', 'into',
|
|
15
|
+
'MiddlewareBase', 'FtResponse', 'unqid']
|
|
16
16
|
|
|
17
17
|
# %% ../nbs/api/00_core.ipynb #23503b9e
|
|
18
|
-
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
|
|
19
20
|
|
|
20
21
|
from fastcore.utils import *
|
|
21
22
|
from fastcore.xml import *
|
|
@@ -29,7 +30,7 @@ from dataclasses import dataclass
|
|
|
29
30
|
from inspect import Parameter,get_annotations
|
|
30
31
|
from functools import partialmethod, update_wrapper
|
|
31
32
|
from http import cookies
|
|
32
|
-
from urllib.parse import urlencode, parse_qs, quote, unquote
|
|
33
|
+
from urllib.parse import urlencode, parse_qs, quote, unquote, urlsplit, urlunsplit
|
|
33
34
|
from copy import deepcopy
|
|
34
35
|
from warnings import warn
|
|
35
36
|
from dateutil import parser as dtparse
|
|
@@ -964,6 +965,26 @@ class StaticNoCache(StaticFiles):
|
|
|
964
965
|
resp.headers.setdefault("Cache-Control", "no-cache")
|
|
965
966
|
return resp
|
|
966
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
|
+
|
|
967
988
|
# %% ../nbs/api/00_core.ipynb #7189daf8
|
|
968
989
|
from functools import wraps
|
|
969
990
|
from inspect import signature, isawaitable
|
|
@@ -1054,10 +1075,10 @@ devtools_loc = "/.well-known/appspecific/com.chrome.devtools.json"
|
|
|
1054
1075
|
@patch
|
|
1055
1076
|
def devtools_json(self:FastHTML, path=None, uuid=None):
|
|
1056
1077
|
if not path: path = Path().absolute()
|
|
1057
|
-
if not uuid: uuid =
|
|
1078
|
+
if not uuid: uuid = str(uuid5(NAMESPACE_URL, str(path)))
|
|
1058
1079
|
@self.route(devtools_loc)
|
|
1059
1080
|
def devtools():
|
|
1060
|
-
return dict(workspace=dict(root=path, uuid=uuid))
|
|
1081
|
+
return dict(workspace=dict(root=str(path), uuid=uuid))
|
|
1061
1082
|
|
|
1062
1083
|
# %% ../nbs/api/00_core.ipynb #e27908c0
|
|
1063
1084
|
@patch
|
|
@@ -5,14 +5,14 @@ Docs: https://www.fastht.ml/docs/api/jupyter.html.md"""
|
|
|
5
5
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/06_jupyter.ipynb.
|
|
6
6
|
|
|
7
7
|
# %% auto #0
|
|
8
|
-
__all__ = ['nb_serve', 'nb_serve_async', '
|
|
9
|
-
'htmx_config_port', 'JupyUvi', 'JupyUviAsync', 'HTMX', 'ws_client']
|
|
8
|
+
__all__ = ['nb_serve', 'nb_serve_async', 'show', 'render_ft', 'htmx_config_port', 'JupyUvi', 'JupyUviAsync', 'HTMX', 'ws_client']
|
|
10
9
|
|
|
11
10
|
# %% ../nbs/api/06_jupyter.ipynb #2c69d9d0
|
|
12
|
-
import asyncio,
|
|
11
|
+
import asyncio, time, uvicorn
|
|
13
12
|
from threading import Thread
|
|
14
13
|
from fastcore.utils import *
|
|
15
14
|
from fastcore.meta import delegates
|
|
15
|
+
from fastcore.net import wait_port_free, wait_port_free_async
|
|
16
16
|
from .common import *
|
|
17
17
|
from .common import show as _show
|
|
18
18
|
from fastcore.parallel import startthread
|
|
@@ -36,33 +36,6 @@ async def nb_serve_async(app, log_level="error", port=8000, host='0.0.0.0', **kw
|
|
|
36
36
|
while not server.started: await asyncio.sleep(0.01)
|
|
37
37
|
return server
|
|
38
38
|
|
|
39
|
-
# %% ../nbs/api/06_jupyter.ipynb #508917bc
|
|
40
|
-
def is_port_free(port, host='localhost'):
|
|
41
|
-
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
42
|
-
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
43
|
-
try:
|
|
44
|
-
sock.bind((host, port))
|
|
45
|
-
sock.listen(1)
|
|
46
|
-
return True
|
|
47
|
-
except OSError: return False
|
|
48
|
-
finally: sock.close()
|
|
49
|
-
|
|
50
|
-
# %% ../nbs/api/06_jupyter.ipynb #1779cb76
|
|
51
|
-
def wait_port_free(port, host='localhost', max_wait=20):
|
|
52
|
-
"Wait for `port` to be free on `host`"
|
|
53
|
-
start_time = time.time()
|
|
54
|
-
while not is_port_free(port, host):
|
|
55
|
-
if time.time() - start_time > max_wait: raise TimeoutError(f"Port {host}:{port} not free after {max_wait}s")
|
|
56
|
-
time.sleep(0.1)
|
|
57
|
-
|
|
58
|
-
async def wait_port_free_async(port, host='localhost', max_wait=20):
|
|
59
|
-
"Async wait for `port` to be free on `host`"
|
|
60
|
-
start_time = time.time()
|
|
61
|
-
while not is_port_free(port, host):
|
|
62
|
-
if time.time() - start_time > max_wait: raise TimeoutError(f"Port {host}:{port} not free after {max_wait}s")
|
|
63
|
-
await asyncio.sleep(0.1)
|
|
64
|
-
|
|
65
|
-
|
|
66
39
|
# %% ../nbs/api/06_jupyter.ipynb #654b36bb
|
|
67
40
|
@delegates(_show)
|
|
68
41
|
def show(*s, **kwargs):
|
|
@@ -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.
|
|
15
|
+
dependencies = ['fastcore>=2.1.2', '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', '
|
|
25
|
+
dev = ['ipython', 'lxml', 'pysym2md>=0.0.6', 'monsterui', 'PyJWT']
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
[project.scripts]
|
|
@@ -44,3 +44,5 @@ lib_path = "fasthtml"
|
|
|
44
44
|
|
|
45
45
|
[tool.chkstyle]
|
|
46
46
|
skip_paths = ["_modidx.py"]
|
|
47
|
+
ignore = ["closing-bracket", "inefficient-multiline-signature", "inefficient-multiline-expression"]
|
|
48
|
+
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-fasthtml
|
|
3
|
+
Version: 0.14.7
|
|
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.1.2
|
|
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
|